blob: 07a137e95883525e1247461c9e86d660505e9649 [file] [log] [blame]
Thomas Vachuskac40d4632015-04-09 16:55:03 -07001/*
2 * Copyright 2015 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 */
16package org.onosproject.provider.nil;
17
18import org.jboss.netty.util.HashedWheelTimer;
19import org.jboss.netty.util.Timeout;
20import org.jboss.netty.util.TimerTask;
21import org.onlab.packet.Ethernet;
22import org.onlab.packet.ICMP;
23import org.onlab.util.Timer;
24import org.onosproject.net.ConnectPoint;
25import org.onosproject.net.Device;
26import org.onosproject.net.PortNumber;
27import org.onosproject.net.device.DeviceAdminService;
28import org.onosproject.net.host.HostService;
29import org.onosproject.net.packet.DefaultInboundPacket;
30import org.onosproject.net.packet.DefaultPacketContext;
31import org.onosproject.net.packet.InboundPacket;
32import org.onosproject.net.packet.OutboundPacket;
33import org.onosproject.net.packet.PacketProvider;
34import org.onosproject.net.packet.PacketProviderService;
35import org.slf4j.Logger;
36
37import 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;
43import static java.util.concurrent.TimeUnit.SECONDS;
44import static org.onosproject.net.MastershipRole.MASTER;
45import static org.slf4j.LoggerFactory.getLogger;
46
47/**
48 * Provider which generates simulated packets and acts as a sink for outbound
49 * packets. To be used for benchmarking only.
50 */
51class NullPacketProvider extends NullProviders.AbstractNullProvider
52 implements PacketProvider {
53
54 private static final int INITIAL_DELAY = 5;
55 private final Logger log = getLogger(getClass());
56
57 // Arbitrary host src/dst
58 private static final int SRC_HOST = 2;
59 private static final int DST_HOST = 5;
60
61 // Time between event firing, in milliseconds
62 private int delay;
63
64 // TODO: use host service to pick legitimate hosts connected to devices
65 private HostService hostService;
66 private PacketProviderService providerService;
67
68 private List<Device> devices;
69 private int currentDevice = 0;
70
71 private HashedWheelTimer timer = Timer.getTimer();
72 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);
93 timeout = timer.newTimeout(new PacketDriverTask(), INITIAL_DELAY, SECONDS);
94 }
95
96 /**
97 * Adjusts packet rate.
98 *
99 * @param packetRate new packet rate
100 */
101 void adjustRate(int packetRate) {
102 delay = 1000 / packetRate;
103 log.info("Settings: packetRate={}, delay={}", packetRate, delay);
104 }
105
106 /**
107 * Stops the packet generation process.
108 */
109 void stop() {
110 if (timeout != null) {
111 timeout.cancel();
112 }
113 }
114
115 @Override
116 public void emit(OutboundPacket packet) {
117 // We don't have a network to emit to. Keep a counter here, maybe?
118 }
119
120 /**
121 * Generates packet events at a given rate.
122 */
123 private class PacketDriverTask implements TimerTask {
124
125 // Filler echo request
126 ICMP icmp;
127 Ethernet eth;
128
129 public PacketDriverTask() {
130 icmp = new ICMP();
131 icmp.setIcmpType((byte) 8).setIcmpCode((byte) 0).setChecksum((short) 0);
132 eth = new Ethernet();
133 eth.setEtherType(Ethernet.TYPE_IPV4);
134 eth.setPayload(icmp);
135 }
136
137 @Override
138 public void run(Timeout to) {
Thomas Vachuskaa7a0f562015-04-14 23:27:44 -0700139 if (!devices.isEmpty() && !to.isCancelled()) {
Thomas Vachuska5c3fd702015-05-01 11:16:53 -0700140 sendEvent(devices.get(Math.min(currentDevice, devices.size() - 1)));
Thomas Vachuskac40d4632015-04-09 16:55:03 -0700141 currentDevice = (currentDevice + 1) % devices.size();
142 timeout = timer.newTimeout(to.getTask(), delay, TimeUnit.MILLISECONDS);
143 }
144 }
145
146 private void sendEvent(Device device) {
147 // Make it look like things came from ports attached to hosts
148 eth.setSourceMACAddress("00:00:10:00:00:0" + SRC_HOST)
149 .setDestinationMACAddress("00:00:10:00:00:0" + DST_HOST);
150 InboundPacket inPkt = new DefaultInboundPacket(
151 new ConnectPoint(device.id(), PortNumber.portNumber(SRC_HOST)),
152 eth, ByteBuffer.wrap(eth.serialize()));
153 providerService.processPacket(new NullPacketContext(inPkt, null));
154 }
155 }
156
157 // Minimal PacketContext to make core and applications happy.
158 private final class NullPacketContext extends DefaultPacketContext {
159 private NullPacketContext(InboundPacket inPkt, OutboundPacket outPkt) {
160 super(System.currentTimeMillis(), inPkt, outPkt, false);
161 }
162
163 @Override
164 public void send() {
165 // We don't send anything out.
166 }
167 }
168
169}