blob: ce289089316068168806e962b7277ce838378fa3 [file] [log] [blame]
Rusty Eddy95421642015-10-21 17:22:13 -07001/*
Rusty Eddybcad55b2016-02-11 18:56:09 -08002 * Copyright 2015, 2016 Open Networking Laboratory
Rusty Eddy95421642015-10-21 17:22:13 -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.pim.impl;
17
18import org.onlab.packet.Ethernet;
19import org.onlab.packet.IPv4;
Rusty Eddy4d5a92f2016-01-25 17:12:14 -080020import org.onlab.packet.Ip4Address;
Rusty Eddy95421642015-10-21 17:22:13 -070021import org.onlab.packet.IpAddress;
Rusty Eddybcad55b2016-02-11 18:56:09 -080022import org.onlab.packet.IpPrefix;
Rusty Eddy95421642015-10-21 17:22:13 -070023import org.onlab.packet.MacAddress;
24import org.onlab.packet.PIM;
25import org.onlab.packet.pim.PIMHello;
26import org.onlab.packet.pim.PIMHelloOption;
Rusty Eddybcad55b2016-02-11 18:56:09 -080027import org.onlab.packet.pim.PIMJoinPrune;
28import org.onlab.packet.pim.PIMJoinPruneGroup;
Rusty Eddy95421642015-10-21 17:22:13 -070029import org.onosproject.incubator.net.intf.Interface;
Jonathan Hart36fd31e2016-01-28 15:55:31 -080030import org.onosproject.net.flow.DefaultTrafficTreatment;
31import org.onosproject.net.flow.TrafficTreatment;
Rusty Eddy95421642015-10-21 17:22:13 -070032import org.onosproject.net.host.InterfaceIpAddress;
Jonathan Hart36fd31e2016-01-28 15:55:31 -080033import org.onosproject.net.packet.DefaultOutboundPacket;
34import org.onosproject.net.packet.PacketService;
Rusty Eddy95421642015-10-21 17:22:13 -070035import org.slf4j.Logger;
Rusty Eddy95421642015-10-21 17:22:13 -070036
Jonathan Hart36fd31e2016-01-28 15:55:31 -080037import java.nio.ByteBuffer;
Jonathan Hart54119bb2016-02-06 18:48:27 -080038import java.util.Collection;
Rusty Eddy390498d2016-01-15 19:21:32 -080039import java.util.HashMap;
40import java.util.Map;
Jonathan Hart5af5f142016-01-28 18:45:27 -080041import java.util.Random;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080042import java.util.Set;
Jonathan Hart6be70952016-02-12 21:11:26 -080043import java.util.concurrent.TimeUnit;
Jonathan Hart54119bb2016-02-06 18:48:27 -080044import java.util.stream.Collectors;
Rusty Eddy95421642015-10-21 17:22:13 -070045
Jonathan Hart5af5f142016-01-28 18:45:27 -080046import static com.google.common.base.Preconditions.checkArgument;
Rusty Eddy390498d2016-01-15 19:21:32 -080047import static com.google.common.base.Preconditions.checkNotNull;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080048import static org.slf4j.LoggerFactory.getLogger;
Rusty Eddy95421642015-10-21 17:22:13 -070049
50/**
Ray Milkeya059a702016-01-12 11:10:33 -080051 * PIM Interface represents an ONOS Interface with IP and MAC addresses for
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080052 * a given ConnectPoint.
Rusty Eddy95421642015-10-21 17:22:13 -070053 */
Jonathan Hart5af5f142016-01-28 18:45:27 -080054public final class PIMInterface {
Rusty Eddy95421642015-10-21 17:22:13 -070055
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080056 private final Logger log = getLogger(getClass());
Rusty Eddy95421642015-10-21 17:22:13 -070057
Jonathan Hart36fd31e2016-01-28 15:55:31 -080058 private final PacketService packetService;
59
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080060 private Interface onosInterface;
Jonathan Hart36fd31e2016-01-28 15:55:31 -080061 private final TrafficTreatment outputTreatment;
Rusty Eddy95421642015-10-21 17:22:13 -070062
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080063 // Our hello opt holdtime
64 private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
Rusty Eddy95421642015-10-21 17:22:13 -070065
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080066 // Our hello opt prune delay
67 private int pruneDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
Rusty Eddy95421642015-10-21 17:22:13 -070068
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080069 // Neighbor priority
70 private int priority = PIMHelloOption.DEFAULT_PRIORITY;
Rusty Eddy95421642015-10-21 17:22:13 -070071
Jonathan Hart6be70952016-02-12 21:11:26 -080072 private final int helloInterval;
73
74 private long lastHello;
75
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080076 // Our current genid
Jonathan Hart5af5f142016-01-28 18:45:27 -080077 private final int generationId;
Rusty Eddy95421642015-10-21 17:22:13 -070078
Rusty Eddy390498d2016-01-15 19:21:32 -080079 // The IP address of the DR
Jonathan Hart5af5f142016-01-28 18:45:27 -080080 private IpAddress drIpaddress;
Rusty Eddy390498d2016-01-15 19:21:32 -080081
82 // A map of all our PIM neighbors keyed on our neighbors IP address
83 private Map<IpAddress, PIMNeighbor> pimNeighbors = new HashMap<>();
84
Rusty Eddy95421642015-10-21 17:22:13 -070085 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080086 * Create a PIMInterface from an ONOS Interface.
Charles Chan30ba4002015-11-05 14:45:16 -080087 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080088 * @param intf the ONOS Interface.
Jonathan Hart5af5f142016-01-28 18:45:27 -080089 * @param holdTime hold time
90 * @param priority priority
91 * @param propagationDelay propagation delay
92 * @param overrideInterval override interval
93 * @param packetService reference to the packet service
Rusty Eddy95421642015-10-21 17:22:13 -070094 */
Jonathan Hart5af5f142016-01-28 18:45:27 -080095 private PIMInterface(Interface intf,
Jonathan Hart6be70952016-02-12 21:11:26 -080096 int helloInterval,
97 short holdTime,
98 int priority,
99 short propagationDelay,
100 short overrideInterval,
101 PacketService packetService) {
Jonathan Hart5af5f142016-01-28 18:45:27 -0800102
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800103 onosInterface = intf;
Jonathan Hart36fd31e2016-01-28 15:55:31 -0800104 outputTreatment = createOutputTreatment();
Jonathan Hart6be70952016-02-12 21:11:26 -0800105 this.helloInterval = helloInterval;
Jonathan Hart5af5f142016-01-28 18:45:27 -0800106 this.holdtime = holdTime;
Jonathan Hart36fd31e2016-01-28 15:55:31 -0800107 this.packetService = packetService;
Rusty Eddy390498d2016-01-15 19:21:32 -0800108 IpAddress ourIp = getIpAddress();
109 MacAddress mac = intf.mac();
110
Jonathan Hart6be70952016-02-12 21:11:26 -0800111 lastHello = 0;
112
Jonathan Hart5af5f142016-01-28 18:45:27 -0800113 generationId = new Random().nextInt();
114
Rusty Eddy390498d2016-01-15 19:21:32 -0800115 // Create a PIM Neighbor to represent ourselves for DR election.
Jonathan Hart54119bb2016-02-06 18:48:27 -0800116 PIMNeighbor us = new PIMNeighbor(ourIp, mac, holdTime, 0, priority, generationId);
Rusty Eddy390498d2016-01-15 19:21:32 -0800117
118 pimNeighbors.put(ourIp, us);
119 drIpaddress = ourIp;
Rusty Eddy95421642015-10-21 17:22:13 -0700120 }
121
Jonathan Hart36fd31e2016-01-28 15:55:31 -0800122 private TrafficTreatment createOutputTreatment() {
123 return DefaultTrafficTreatment.builder()
124 .setOutput(onosInterface.connectPoint().port())
125 .build();
126 }
127
Rusty Eddy95421642015-10-21 17:22:13 -0700128 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800129 * Return the ONOS Interface.
Rusty Eddy95421642015-10-21 17:22:13 -0700130 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800131 * @return ONOS Interface.
Rusty Eddy95421642015-10-21 17:22:13 -0700132 */
133 public Interface getInterface() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800134 return onosInterface;
135
Rusty Eddy95421642015-10-21 17:22:13 -0700136 }
137
138 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800139 * Set the ONOS Interface, it will override a previous value.
Rusty Eddy95421642015-10-21 17:22:13 -0700140 *
Jian Lidfba7392016-01-22 16:46:58 -0800141 * @param intf ONOS Interface
142 * @return PIM interface instance
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800143 */
144 public PIMInterface setInterface(Interface intf) {
Rusty Eddy390498d2016-01-15 19:21:32 -0800145 onosInterface = intf;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800146 return this;
147 }
148
149 /**
150 * Get the set of IP Addresses associated with this interface.
151 *
152 * @return a set of Ip Addresses on this interface
153 */
154 public Set<InterfaceIpAddress> getIpAddresses() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800155 return onosInterface.ipAddresses();
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800156 }
157
158 /**
159 * Return a single "best" IP address.
160 *
161 * @return the choosen IP address or null if none
Rusty Eddy95421642015-10-21 17:22:13 -0700162 */
163 public IpAddress getIpAddress() {
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800164 if (onosInterface.ipAddresses().isEmpty()) {
Rusty Eddy95421642015-10-21 17:22:13 -0700165 return null;
166 }
167
Rusty Eddy95421642015-10-21 17:22:13 -0700168 IpAddress ipaddr = null;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800169 for (InterfaceIpAddress ifipaddr : onosInterface.ipAddresses()) {
Rusty Eddy95421642015-10-21 17:22:13 -0700170 ipaddr = ifipaddr.ipAddress();
171 break;
172 }
173 return ipaddr;
174 }
175
176 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800177 * Get the holdtime.
Rusty Eddy95421642015-10-21 17:22:13 -0700178 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800179 * @return the holdtime
180 */
181 public short getHoldtime() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800182 return holdtime;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800183 }
184
185 /**
186 * Get the prune delay.
187 *
188 * @return The prune delay
189 */
190 public int getPruneDelay() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800191 return pruneDelay;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800192 }
193
194 /**
195 * Get our hello priority.
196 *
197 * @return our priority
Rusty Eddy95421642015-10-21 17:22:13 -0700198 */
199 public int getPriority() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800200 return priority;
Rusty Eddy95421642015-10-21 17:22:13 -0700201 }
202
203 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800204 * Get our generation ID.
Rusty Eddy95421642015-10-21 17:22:13 -0700205 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800206 * @return our generation ID
Rusty Eddy95421642015-10-21 17:22:13 -0700207 */
Jonathan Hart5af5f142016-01-28 18:45:27 -0800208 public int getGenerationId() {
209 return generationId;
Rusty Eddy95421642015-10-21 17:22:13 -0700210 }
211
212 /**
Jonathan Hart54119bb2016-02-06 18:48:27 -0800213 * Gets the neighbors seen on this interface.
214 *
215 * @return PIM neighbors
216 */
217 public Collection<PIMNeighbor> getNeighbors() {
218 return pimNeighbors.values();
219 }
220
221 /**
222 * Checks whether any of our neighbors have expired, and cleans up their
223 * state if they have.
224 */
225 public void checkNeighborTimeouts() {
226 Set<PIMNeighbor> expired = pimNeighbors.values().stream()
227 // Don't time ourselves out!
228 .filter(neighbor -> !neighbor.ipAddress().equals(getIpAddress()))
229 .filter(neighbor -> neighbor.isExpired())
230 .collect(Collectors.toSet());
231
232 for (PIMNeighbor neighbor : expired) {
233 log.info("Timing out neighbor {}", neighbor);
234 pimNeighbors.remove(neighbor.ipAddress(), neighbor);
235 }
236 }
237
238 /**
Rusty Eddy4d5a92f2016-01-25 17:12:14 -0800239 * Multicast a hello message out our interface. This hello message is sent
240 * periodically during the normal PIM Neighbor refresh time, as well as a
241 * result of a newly created interface.
242 */
243 public void sendHello() {
Jonathan Hart6be70952016-02-12 21:11:26 -0800244 if (lastHello + TimeUnit.SECONDS.toMillis(helloInterval) >
245 System.currentTimeMillis()) {
246 return;
247 }
248
249 lastHello = System.currentTimeMillis();
250
Rusty Eddy4d5a92f2016-01-25 17:12:14 -0800251 // Create the base PIM Packet and mark it a hello packet
252 PIMPacket pimPacket = new PIMPacket(PIM.TYPE_HELLO);
253
254 // We need to set the source MAC and IPv4 addresses
255 pimPacket.setSrcMacAddr(onosInterface.mac());
256 pimPacket.setSrcIpAddress(Ip4Address.valueOf(getIpAddress().toOctets()));
257
258 // Create the hello message with options
259 PIMHello hello = new PIMHello();
260 hello.createDefaultOptions();
Jonathan Hart5af5f142016-01-28 18:45:27 -0800261 hello.addOption(PIMHelloOption.createHoldTime(holdtime));
262 hello.addOption(PIMHelloOption.createPriority(priority));
263 hello.addOption(PIMHelloOption.createGenID(generationId));
Rusty Eddy4d5a92f2016-01-25 17:12:14 -0800264
265 // Now set the hello option payload
266 pimPacket.setPIMPayload(hello);
267
Jonathan Hart36fd31e2016-01-28 15:55:31 -0800268 packetService.emit(new DefaultOutboundPacket(
269 onosInterface.connectPoint().deviceId(),
270 outputTreatment,
271 ByteBuffer.wrap(pimPacket.getEthernet().serialize())));
Rusty Eddy4d5a92f2016-01-25 17:12:14 -0800272 }
273
274 /**
Rusty Eddy390498d2016-01-15 19:21:32 -0800275 * Process an incoming PIM Hello message. There are a few things going on in
276 * this method:
277 * <ul>
278 * <li>We <em>may</em> have to create a new neighbor if one does not already exist</li>
279 * <li>We <em>may</em> need to re-elect a new DR if new information is received</li>
280 * <li>We <em>may</em> need to send an existing neighbor all joins if the genid changed</li>
Jonathan Hart54119bb2016-02-06 18:48:27 -0800281 * <li>We will refresh the neighbor's timestamp</li>
Rusty Eddy390498d2016-01-15 19:21:32 -0800282 * </ul>
Rusty Eddy95421642015-10-21 17:22:13 -0700283 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800284 * @param ethPkt the Ethernet packet header
Rusty Eddy95421642015-10-21 17:22:13 -0700285 */
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800286 public void processHello(Ethernet ethPkt) {
Rusty Eddy95421642015-10-21 17:22:13 -0700287
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800288 // We'll need to save our neighbors MAC address
289 MacAddress nbrmac = ethPkt.getSourceMAC();
Rusty Eddy95421642015-10-21 17:22:13 -0700290
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800291 // And we'll need to save neighbors IP Address.
292 IPv4 iphdr = (IPv4) ethPkt.getPayload();
293 IpAddress srcip = IpAddress.valueOf(iphdr.getSourceAddress());
Rusty Eddy95421642015-10-21 17:22:13 -0700294
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800295 PIM pimhdr = (PIM) iphdr.getPayload();
296 if (pimhdr.getPimMsgType() != PIM.TYPE_HELLO) {
297 log.error("process Hello has received a non hello packet type: " + pimhdr.getPimMsgType());
Rusty Eddy95421642015-10-21 17:22:13 -0700298 return;
299 }
300
Rusty Eddy390498d2016-01-15 19:21:32 -0800301 // get the DR values for later calculation
302 PIMNeighbor dr = pimNeighbors.get(drIpaddress);
303 checkNotNull(dr);
304
305 IpAddress drip = drIpaddress;
Jonathan Hart54119bb2016-02-06 18:48:27 -0800306 int drpri = dr.priority();
Rusty Eddy390498d2016-01-15 19:21:32 -0800307
308 // Assume we do not need to run a DR election
309 boolean reElectDr = false;
310 boolean genidChanged = false;
311
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800312 PIMHello hello = (PIMHello) pimhdr.getPayload();
313
Rusty Eddy390498d2016-01-15 19:21:32 -0800314 // Determine if we already have a PIMNeighbor
315 PIMNeighbor nbr = pimNeighbors.getOrDefault(srcip, null);
Jonathan Hart54119bb2016-02-06 18:48:27 -0800316 PIMNeighbor newNbr = PIMNeighbor.createPimNeighbor(srcip, nbrmac, hello.getOptions().values());
317
Rusty Eddy390498d2016-01-15 19:21:32 -0800318 if (nbr == null) {
Jonathan Hart54119bb2016-02-06 18:48:27 -0800319 pimNeighbors.putIfAbsent(srcip, newNbr);
320 nbr = newNbr;
321 } else if (!nbr.equals(newNbr)) {
322 if (newNbr.holdtime() == 0) {
323 // Neighbor has shut down. Remove them and clean up
324 pimNeighbors.remove(srcip, nbr);
325 return;
326 } else {
327 // Neighbor has changed one of their options.
328 pimNeighbors.put(srcip, newNbr);
329 nbr = newNbr;
Rusty Eddy390498d2016-01-15 19:21:32 -0800330 }
Rusty Eddy95421642015-10-21 17:22:13 -0700331 }
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800332
Jonathan Hart54119bb2016-02-06 18:48:27 -0800333 // Refresh this neighbor's timestamp
Rusty Eddy390498d2016-01-15 19:21:32 -0800334 nbr.refreshTimestamp();
335
336 /*
Jonathan Hart5af5f142016-01-28 18:45:27 -0800337 * the election method will first determine if an election
Rusty Eddy390498d2016-01-15 19:21:32 -0800338 * needs to be run, if so it will run the election. The
339 * IP address of the DR will be returned. If the IP address
340 * of the DR is different from what we already have we know a
341 * new DR has been elected.
342 */
343 IpAddress electedIp = election(nbr, drip, drpri);
344 if (!drip.equals(electedIp)) {
345 // we have a new DR.
346 drIpaddress = electedIp;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800347 }
Rusty Eddy95421642015-10-21 17:22:13 -0700348 }
349
Rusty Eddy390498d2016-01-15 19:21:32 -0800350 // Run an election if we need to. Return the elected IP address.
Jonathan Hart5af5f142016-01-28 18:45:27 -0800351 private IpAddress election(PIMNeighbor nbr, IpAddress drIp, int drPriority) {
Rusty Eddy390498d2016-01-15 19:21:32 -0800352
Jonathan Hart54119bb2016-02-06 18:48:27 -0800353 IpAddress nbrIp = nbr.ipAddress();
354 if (nbr.priority() > drPriority) {
Jonathan Hart5af5f142016-01-28 18:45:27 -0800355 return nbrIp;
Rusty Eddy390498d2016-01-15 19:21:32 -0800356 }
357
Jonathan Hart5af5f142016-01-28 18:45:27 -0800358 if (nbrIp.compareTo(drIp) > 0) {
359 return nbrIp;
Rusty Eddy390498d2016-01-15 19:21:32 -0800360 }
Jonathan Hart5af5f142016-01-28 18:45:27 -0800361 return drIp;
Rusty Eddy390498d2016-01-15 19:21:32 -0800362 }
363
Rusty Eddy95421642015-10-21 17:22:13 -0700364 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800365 * Process an incoming PIM JoinPrune message.
Rusty Eddy95421642015-10-21 17:22:13 -0700366 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800367 * @param ethPkt the Ethernet packet header.
Rusty Eddy95421642015-10-21 17:22:13 -0700368 */
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800369 public void processJoinPrune(Ethernet ethPkt) {
Rusty Eddybcad55b2016-02-11 18:56:09 -0800370
371 IPv4 ip = (IPv4) ethPkt.getPayload();
372 checkNotNull(ip);
373
374 PIM pim = (PIM) ip.getPayload();
375 checkNotNull(pim);
376
377 PIMJoinPrune jpHdr = (PIMJoinPrune) pim.getPayload();
378 checkNotNull(jpHdr);
379
380 /*
381 * The Join/Prune messages are grouped by Group address. We'll walk each group address
382 * where we will possibly have to walk a list of source address for the joins and prunes.
383 */
384 Collection<PIMJoinPruneGroup> jpgs = jpHdr.getJoinPrunes();
385 for (PIMJoinPruneGroup jpg : jpgs) {
386 IpPrefix gpfx = jpg.getGroup();
387
388 // Walk the joins first.
389 for (IpPrefix spfx : jpg.getJoins().values()) {
390
391 // We may need
392
393
394 }
395
396 for (IpPrefix spfx : jpg.getPrunes().values()) {
397
398 // TODO: this is where we many need to remove multi-cast state and possibly intents.
399
400 }
401 }
402
Rusty Eddy95421642015-10-21 17:22:13 -0700403 }
Jonathan Hart5af5f142016-01-28 18:45:27 -0800404
405 /**
406 * Returns a builder for a PIM interface.
407 *
408 * @return PIM interface builder
409 */
410 public static Builder builder() {
411 return new Builder();
412 }
413
414 /**
415 * Builder for a PIM interface.
416 */
417 public static class Builder {
418 private Interface intf;
419 private PacketService packetService;
Jonathan Hart6be70952016-02-12 21:11:26 -0800420 private int helloInterval = PIMInterfaceManager.DEFAULT_HELLO_INTERVAL;
Jonathan Hart5af5f142016-01-28 18:45:27 -0800421 private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
422 private int priority = PIMHelloOption.DEFAULT_PRIORITY;
423 private short propagationDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
424 private short overrideInterval = PIMHelloOption.DEFAULT_OVERRIDEINTERVAL;
425
426 /**
427 * Uses the specified ONOS interface.
428 *
429 * @param intf ONOS interface
430 * @return this PIM interface builder
431 */
432 public Builder withInterface(Interface intf) {
433 this.intf = checkNotNull(intf);
434 return this;
435 }
436
437 /**
438 * Sets the reference to the packet service.
439 *
440 * @param packetService packet service
441 * @return this PIM interface builder
442 */
443 public Builder withPacketService(PacketService packetService) {
444 this.packetService = checkNotNull(packetService);
445 return this;
446 }
447
448 /**
Jonathan Hart6be70952016-02-12 21:11:26 -0800449 * Users the specified hello interval.
450 *
451 * @param helloInterval hello interval in seconds
452 * @return this PIM interface builder
453 */
454 public Builder withHelloInterval(int helloInterval) {
455 this.helloInterval = helloInterval;
456 return this;
457 }
458
459 /**
Jonathan Hart5af5f142016-01-28 18:45:27 -0800460 * Uses the specified hold time.
461 *
462 * @param holdTime hold time in seconds
463 * @return this PIM interface builder
464 */
465 public Builder withHoldTime(short holdTime) {
466 this.holdtime = holdTime;
467 return this;
468 }
469
470 /**
471 * Uses the specified DR priority.
472 *
473 * @param priority DR priority
474 * @return this PIM interface builder
475 */
476 public Builder withPriority(int priority) {
477 this.priority = priority;
478 return this;
479 }
480
481 /**
482 * Uses the specified propagation delay.
483 *
484 * @param propagationDelay propagation delay in ms
485 * @return this PIM interface builder
486 */
487 public Builder withPropagationDelay(short propagationDelay) {
488 this.propagationDelay = propagationDelay;
489 return this;
490 }
491
492 /**
493 * Uses the specified override interval.
494 *
495 * @param overrideInterval override interval in ms
496 * @return this PIM interface builder
497 */
498 public Builder withOverrideInterval(short overrideInterval) {
499 this.overrideInterval = overrideInterval;
500 return this;
501 }
502
503 /**
504 * Builds the PIM interface.
505 *
506 * @return PIM interface
507 */
508 public PIMInterface build() {
509 checkArgument(intf != null, "Must provide an interface");
510 checkArgument(packetService != null, "Must provide a packet service");
511
Jonathan Hart6be70952016-02-12 21:11:26 -0800512 return new PIMInterface(intf, helloInterval, holdtime, priority,
513 propagationDelay, overrideInterval, packetService);
Jonathan Hart5af5f142016-01-28 18:45:27 -0800514 }
515
516 }
Rusty Eddy95421642015-10-21 17:22:13 -0700517}