blob: d69a0acc17442679d62c3548fc3e0144a9713fb4 [file] [log] [blame]
Thomas Vachuskac40d4632015-04-09 16:55:03 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuskac40d4632015-04-09 16:55:03 -07003 *
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 */
16package org.onosproject.provider.nil;
17
Thomas Vachuskac40d4632015-04-09 16:55:03 -070018import org.onlab.packet.Ethernet;
19import org.onlab.packet.ICMP;
20import org.onlab.util.Timer;
21import org.onosproject.net.ConnectPoint;
22import org.onosproject.net.Device;
23import org.onosproject.net.PortNumber;
24import org.onosproject.net.device.DeviceAdminService;
25import org.onosproject.net.host.HostService;
26import org.onosproject.net.packet.DefaultInboundPacket;
27import org.onosproject.net.packet.DefaultPacketContext;
28import org.onosproject.net.packet.InboundPacket;
29import org.onosproject.net.packet.OutboundPacket;
30import org.onosproject.net.packet.PacketProvider;
31import org.onosproject.net.packet.PacketProviderService;
32import org.slf4j.Logger;
33
Yuta HIGUCHI19afc032017-05-20 23:44:17 -070034import io.netty.util.Timeout;
35import io.netty.util.TimerTask;
36
Thomas Vachuskac40d4632015-04-09 16:55:03 -070037import java.nio.ByteBuffer;
38import java.util.List;
39import java.util.concurrent.TimeUnit;
40import java.util.stream.Collectors;
41
42import static com.google.common.collect.ImmutableList.copyOf;
Thomas Vachuskac3cdf902016-04-13 13:44:09 -070043import static java.util.concurrent.TimeUnit.MILLISECONDS;
Thomas Vachuskac40d4632015-04-09 16:55:03 -070044import static java.util.concurrent.TimeUnit.SECONDS;
45import static org.onosproject.net.MastershipRole.MASTER;
46import static org.slf4j.LoggerFactory.getLogger;
47
48/**
49 * Provider which generates simulated packets and acts as a sink for outbound
50 * packets. To be used for benchmarking only.
51 */
52class NullPacketProvider extends NullProviders.AbstractNullProvider
53 implements PacketProvider {
54
55 private static final int INITIAL_DELAY = 5;
56 private final Logger log = getLogger(getClass());
57
58 // Arbitrary host src/dst
59 private static final int SRC_HOST = 2;
60 private static final int DST_HOST = 5;
61
62 // Time between event firing, in milliseconds
63 private int delay;
64
65 // TODO: use host service to pick legitimate hosts connected to devices
66 private HostService hostService;
67 private PacketProviderService providerService;
68
69 private List<Device> devices;
70 private int currentDevice = 0;
71
Thomas Vachuskac40d4632015-04-09 16:55:03 -070072 private Timeout timeout;
73
74 /**
75 * Starts the packet generation process.
76 *
77 * @param packetRate packets per second
78 * @param hostService host service
79 * @param deviceService device service
80 * @param providerService packet provider service
81 */
82 void start(int packetRate, HostService hostService,
83 DeviceAdminService deviceService,
84 PacketProviderService providerService) {
85 this.hostService = hostService;
86 this.providerService = providerService;
87
88 this.devices = copyOf(deviceService.getDevices()).stream()
89 .filter(d -> deviceService.getRole(d.id()) == MASTER)
90 .collect(Collectors.toList());
91
92 adjustRate(packetRate);
Yuta HIGUCHI19afc032017-05-20 23:44:17 -070093 timeout = Timer.newTimeout(new PacketDriverTask(), INITIAL_DELAY, SECONDS);
Thomas Vachuskac40d4632015-04-09 16:55:03 -070094 }
95
96 /**
97 * Adjusts packet rate.
98 *
99 * @param packetRate new packet rate
100 */
101 void adjustRate(int packetRate) {
Thomas Vachuskac3cdf902016-04-13 13:44:09 -0700102 boolean needsRestart = delay == 0 && packetRate > 0;
103 delay = packetRate > 0 ? 1000 / packetRate : 0;
104 if (needsRestart) {
Yuta HIGUCHI19afc032017-05-20 23:44:17 -0700105 timeout = Timer.newTimeout(new PacketDriverTask(), 1, MILLISECONDS);
Thomas Vachuskac3cdf902016-04-13 13:44:09 -0700106 }
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700107 log.info("Settings: packetRate={}, delay={}", packetRate, delay);
108 }
109
110 /**
111 * Stops the packet generation process.
112 */
113 void stop() {
114 if (timeout != null) {
115 timeout.cancel();
116 }
117 }
118
119 @Override
120 public void emit(OutboundPacket packet) {
121 // We don't have a network to emit to. Keep a counter here, maybe?
122 }
123
124 /**
125 * Generates packet events at a given rate.
126 */
127 private class PacketDriverTask implements TimerTask {
128
129 // Filler echo request
130 ICMP icmp;
131 Ethernet eth;
132
Thomas Vachuskac3cdf902016-04-13 13:44:09 -0700133 PacketDriverTask() {
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700134 icmp = new ICMP();
135 icmp.setIcmpType((byte) 8).setIcmpCode((byte) 0).setChecksum((short) 0);
136 eth = new Ethernet();
137 eth.setEtherType(Ethernet.TYPE_IPV4);
138 eth.setPayload(icmp);
139 }
140
141 @Override
142 public void run(Timeout to) {
Thomas Vachuskac3cdf902016-04-13 13:44:09 -0700143 if (!devices.isEmpty() && !to.isCancelled() && delay > 0) {
Thomas Vachuska5c3fd702015-05-01 11:16:53 -0700144 sendEvent(devices.get(Math.min(currentDevice, devices.size() - 1)));
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700145 currentDevice = (currentDevice + 1) % devices.size();
Yuta HIGUCHI19afc032017-05-20 23:44:17 -0700146 timeout = to.timer().newTimeout(to.task(), delay, TimeUnit.MILLISECONDS);
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700147 }
148 }
149
150 private void sendEvent(Device device) {
151 // Make it look like things came from ports attached to hosts
Thomas Vachuskac3cdf902016-04-13 13:44:09 -0700152 eth.setSourceMACAddress("00:00:00:10:00:0" + SRC_HOST)
153 .setDestinationMACAddress("00:00:00:10:00:0" + DST_HOST);
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700154 InboundPacket inPkt = new DefaultInboundPacket(
155 new ConnectPoint(device.id(), PortNumber.portNumber(SRC_HOST)),
156 eth, ByteBuffer.wrap(eth.serialize()));
157 providerService.processPacket(new NullPacketContext(inPkt, null));
158 }
159 }
160
161 // Minimal PacketContext to make core and applications happy.
162 private final class NullPacketContext extends DefaultPacketContext {
163 private NullPacketContext(InboundPacket inPkt, OutboundPacket outPkt) {
164 super(System.currentTimeMillis(), inPkt, outPkt, false);
165 }
166
167 @Override
168 public void send() {
169 // We don't send anything out.
170 }
171 }
172
173}