blob: 30d08c8cbaec5ec099729185d0be2f67731a310d [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 Hart54119bb2016-02-06 18:48:27 -080043import java.util.stream.Collectors;
Rusty Eddy95421642015-10-21 17:22:13 -070044
Jonathan Hart5af5f142016-01-28 18:45:27 -080045import static com.google.common.base.Preconditions.checkArgument;
Rusty Eddy390498d2016-01-15 19:21:32 -080046import static com.google.common.base.Preconditions.checkNotNull;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080047import static org.slf4j.LoggerFactory.getLogger;
Rusty Eddy95421642015-10-21 17:22:13 -070048
49/**
Ray Milkeya059a702016-01-12 11:10:33 -080050 * PIM Interface represents an ONOS Interface with IP and MAC addresses for
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080051 * a given ConnectPoint.
Rusty Eddy95421642015-10-21 17:22:13 -070052 */
Jonathan Hart5af5f142016-01-28 18:45:27 -080053public final class PIMInterface {
Rusty Eddy95421642015-10-21 17:22:13 -070054
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080055 private final Logger log = getLogger(getClass());
Rusty Eddy95421642015-10-21 17:22:13 -070056
Jonathan Hart36fd31e2016-01-28 15:55:31 -080057 private final PacketService packetService;
58
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080059 private Interface onosInterface;
Jonathan Hart36fd31e2016-01-28 15:55:31 -080060 private final TrafficTreatment outputTreatment;
Rusty Eddy95421642015-10-21 17:22:13 -070061
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080062 // Our hello opt holdtime
63 private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
Rusty Eddy95421642015-10-21 17:22:13 -070064
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080065 // Our hello opt prune delay
66 private int pruneDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
Rusty Eddy95421642015-10-21 17:22:13 -070067
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080068 // Neighbor priority
69 private int priority = PIMHelloOption.DEFAULT_PRIORITY;
Rusty Eddy95421642015-10-21 17:22:13 -070070
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080071 // Our current genid
Jonathan Hart5af5f142016-01-28 18:45:27 -080072 private final int generationId;
Rusty Eddy95421642015-10-21 17:22:13 -070073
Rusty Eddy390498d2016-01-15 19:21:32 -080074 // The IP address of the DR
Jonathan Hart5af5f142016-01-28 18:45:27 -080075 private IpAddress drIpaddress;
Rusty Eddy390498d2016-01-15 19:21:32 -080076
77 // A map of all our PIM neighbors keyed on our neighbors IP address
78 private Map<IpAddress, PIMNeighbor> pimNeighbors = new HashMap<>();
79
Rusty Eddy95421642015-10-21 17:22:13 -070080 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080081 * Create a PIMInterface from an ONOS Interface.
Charles Chan30ba4002015-11-05 14:45:16 -080082 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080083 * @param intf the ONOS Interface.
Jonathan Hart5af5f142016-01-28 18:45:27 -080084 * @param holdTime hold time
85 * @param priority priority
86 * @param propagationDelay propagation delay
87 * @param overrideInterval override interval
88 * @param packetService reference to the packet service
Rusty Eddy95421642015-10-21 17:22:13 -070089 */
Jonathan Hart5af5f142016-01-28 18:45:27 -080090 private PIMInterface(Interface intf,
91 short holdTime,
92 int priority,
93 short propagationDelay,
94 short overrideInterval,
95 PacketService packetService) {
96
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080097 onosInterface = intf;
Jonathan Hart36fd31e2016-01-28 15:55:31 -080098 outputTreatment = createOutputTreatment();
Jonathan Hart5af5f142016-01-28 18:45:27 -080099 this.holdtime = holdTime;
Jonathan Hart36fd31e2016-01-28 15:55:31 -0800100 this.packetService = packetService;
Rusty Eddy390498d2016-01-15 19:21:32 -0800101 IpAddress ourIp = getIpAddress();
102 MacAddress mac = intf.mac();
103
Jonathan Hart5af5f142016-01-28 18:45:27 -0800104 generationId = new Random().nextInt();
105
Rusty Eddy390498d2016-01-15 19:21:32 -0800106 // Create a PIM Neighbor to represent ourselves for DR election.
Jonathan Hart54119bb2016-02-06 18:48:27 -0800107 PIMNeighbor us = new PIMNeighbor(ourIp, mac, holdTime, 0, priority, generationId);
Rusty Eddy390498d2016-01-15 19:21:32 -0800108
109 pimNeighbors.put(ourIp, us);
110 drIpaddress = ourIp;
Rusty Eddy95421642015-10-21 17:22:13 -0700111 }
112
Jonathan Hart36fd31e2016-01-28 15:55:31 -0800113 private TrafficTreatment createOutputTreatment() {
114 return DefaultTrafficTreatment.builder()
115 .setOutput(onosInterface.connectPoint().port())
116 .build();
117 }
118
Rusty Eddy95421642015-10-21 17:22:13 -0700119 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800120 * Return the ONOS Interface.
Rusty Eddy95421642015-10-21 17:22:13 -0700121 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800122 * @return ONOS Interface.
Rusty Eddy95421642015-10-21 17:22:13 -0700123 */
124 public Interface getInterface() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800125 return onosInterface;
126
Rusty Eddy95421642015-10-21 17:22:13 -0700127 }
128
129 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800130 * Set the ONOS Interface, it will override a previous value.
Rusty Eddy95421642015-10-21 17:22:13 -0700131 *
Jian Lidfba7392016-01-22 16:46:58 -0800132 * @param intf ONOS Interface
133 * @return PIM interface instance
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800134 */
135 public PIMInterface setInterface(Interface intf) {
Rusty Eddy390498d2016-01-15 19:21:32 -0800136 onosInterface = intf;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800137 return this;
138 }
139
140 /**
141 * Get the set of IP Addresses associated with this interface.
142 *
143 * @return a set of Ip Addresses on this interface
144 */
145 public Set<InterfaceIpAddress> getIpAddresses() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800146 return onosInterface.ipAddresses();
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800147 }
148
149 /**
150 * Return a single "best" IP address.
151 *
152 * @return the choosen IP address or null if none
Rusty Eddy95421642015-10-21 17:22:13 -0700153 */
154 public IpAddress getIpAddress() {
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800155 if (onosInterface.ipAddresses().isEmpty()) {
Rusty Eddy95421642015-10-21 17:22:13 -0700156 return null;
157 }
158
Rusty Eddy95421642015-10-21 17:22:13 -0700159 IpAddress ipaddr = null;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800160 for (InterfaceIpAddress ifipaddr : onosInterface.ipAddresses()) {
Rusty Eddy95421642015-10-21 17:22:13 -0700161 ipaddr = ifipaddr.ipAddress();
162 break;
163 }
164 return ipaddr;
165 }
166
167 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800168 * Get the holdtime.
Rusty Eddy95421642015-10-21 17:22:13 -0700169 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800170 * @return the holdtime
171 */
172 public short getHoldtime() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800173 return holdtime;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800174 }
175
176 /**
177 * Get the prune delay.
178 *
179 * @return The prune delay
180 */
181 public int getPruneDelay() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800182 return pruneDelay;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800183 }
184
185 /**
186 * Get our hello priority.
187 *
188 * @return our priority
Rusty Eddy95421642015-10-21 17:22:13 -0700189 */
190 public int getPriority() {
Rusty Eddy390498d2016-01-15 19:21:32 -0800191 return priority;
Rusty Eddy95421642015-10-21 17:22:13 -0700192 }
193
194 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800195 * Get our generation ID.
Rusty Eddy95421642015-10-21 17:22:13 -0700196 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800197 * @return our generation ID
Rusty Eddy95421642015-10-21 17:22:13 -0700198 */
Jonathan Hart5af5f142016-01-28 18:45:27 -0800199 public int getGenerationId() {
200 return generationId;
Rusty Eddy95421642015-10-21 17:22:13 -0700201 }
202
203 /**
Jonathan Hart54119bb2016-02-06 18:48:27 -0800204 * Gets the neighbors seen on this interface.
205 *
206 * @return PIM neighbors
207 */
208 public Collection<PIMNeighbor> getNeighbors() {
209 return pimNeighbors.values();
210 }
211
212 /**
213 * Checks whether any of our neighbors have expired, and cleans up their
214 * state if they have.
215 */
216 public void checkNeighborTimeouts() {
217 Set<PIMNeighbor> expired = pimNeighbors.values().stream()
218 // Don't time ourselves out!
219 .filter(neighbor -> !neighbor.ipAddress().equals(getIpAddress()))
220 .filter(neighbor -> neighbor.isExpired())
221 .collect(Collectors.toSet());
222
223 for (PIMNeighbor neighbor : expired) {
224 log.info("Timing out neighbor {}", neighbor);
225 pimNeighbors.remove(neighbor.ipAddress(), neighbor);
226 }
227 }
228
229 /**
Rusty Eddy4d5a92f2016-01-25 17:12:14 -0800230 * Multicast a hello message out our interface. This hello message is sent
231 * periodically during the normal PIM Neighbor refresh time, as well as a
232 * result of a newly created interface.
233 */
234 public void sendHello() {
Rusty Eddy4d5a92f2016-01-25 17:12:14 -0800235 // Create the base PIM Packet and mark it a hello packet
236 PIMPacket pimPacket = new PIMPacket(PIM.TYPE_HELLO);
237
238 // We need to set the source MAC and IPv4 addresses
239 pimPacket.setSrcMacAddr(onosInterface.mac());
240 pimPacket.setSrcIpAddress(Ip4Address.valueOf(getIpAddress().toOctets()));
241
242 // Create the hello message with options
243 PIMHello hello = new PIMHello();
244 hello.createDefaultOptions();
Jonathan Hart5af5f142016-01-28 18:45:27 -0800245 hello.addOption(PIMHelloOption.createHoldTime(holdtime));
246 hello.addOption(PIMHelloOption.createPriority(priority));
247 hello.addOption(PIMHelloOption.createGenID(generationId));
Rusty Eddy4d5a92f2016-01-25 17:12:14 -0800248
249 // Now set the hello option payload
250 pimPacket.setPIMPayload(hello);
251
Jonathan Hart36fd31e2016-01-28 15:55:31 -0800252 packetService.emit(new DefaultOutboundPacket(
253 onosInterface.connectPoint().deviceId(),
254 outputTreatment,
255 ByteBuffer.wrap(pimPacket.getEthernet().serialize())));
Rusty Eddy4d5a92f2016-01-25 17:12:14 -0800256 }
257
258 /**
Rusty Eddy390498d2016-01-15 19:21:32 -0800259 * Process an incoming PIM Hello message. There are a few things going on in
260 * this method:
261 * <ul>
262 * <li>We <em>may</em> have to create a new neighbor if one does not already exist</li>
263 * <li>We <em>may</em> need to re-elect a new DR if new information is received</li>
264 * <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 -0800265 * <li>We will refresh the neighbor's timestamp</li>
Rusty Eddy390498d2016-01-15 19:21:32 -0800266 * </ul>
Rusty Eddy95421642015-10-21 17:22:13 -0700267 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800268 * @param ethPkt the Ethernet packet header
Rusty Eddy95421642015-10-21 17:22:13 -0700269 */
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800270 public void processHello(Ethernet ethPkt) {
Rusty Eddy95421642015-10-21 17:22:13 -0700271
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800272 // We'll need to save our neighbors MAC address
273 MacAddress nbrmac = ethPkt.getSourceMAC();
Rusty Eddy95421642015-10-21 17:22:13 -0700274
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800275 // And we'll need to save neighbors IP Address.
276 IPv4 iphdr = (IPv4) ethPkt.getPayload();
277 IpAddress srcip = IpAddress.valueOf(iphdr.getSourceAddress());
Rusty Eddy95421642015-10-21 17:22:13 -0700278
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800279 PIM pimhdr = (PIM) iphdr.getPayload();
280 if (pimhdr.getPimMsgType() != PIM.TYPE_HELLO) {
281 log.error("process Hello has received a non hello packet type: " + pimhdr.getPimMsgType());
Rusty Eddy95421642015-10-21 17:22:13 -0700282 return;
283 }
284
Rusty Eddy390498d2016-01-15 19:21:32 -0800285 // get the DR values for later calculation
286 PIMNeighbor dr = pimNeighbors.get(drIpaddress);
287 checkNotNull(dr);
288
289 IpAddress drip = drIpaddress;
Jonathan Hart54119bb2016-02-06 18:48:27 -0800290 int drpri = dr.priority();
Rusty Eddy390498d2016-01-15 19:21:32 -0800291
292 // Assume we do not need to run a DR election
293 boolean reElectDr = false;
294 boolean genidChanged = false;
295
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800296 PIMHello hello = (PIMHello) pimhdr.getPayload();
297
Rusty Eddy390498d2016-01-15 19:21:32 -0800298 // Determine if we already have a PIMNeighbor
299 PIMNeighbor nbr = pimNeighbors.getOrDefault(srcip, null);
Jonathan Hart54119bb2016-02-06 18:48:27 -0800300 PIMNeighbor newNbr = PIMNeighbor.createPimNeighbor(srcip, nbrmac, hello.getOptions().values());
301
Rusty Eddy390498d2016-01-15 19:21:32 -0800302 if (nbr == null) {
Jonathan Hart54119bb2016-02-06 18:48:27 -0800303 pimNeighbors.putIfAbsent(srcip, newNbr);
304 nbr = newNbr;
305 } else if (!nbr.equals(newNbr)) {
306 if (newNbr.holdtime() == 0) {
307 // Neighbor has shut down. Remove them and clean up
308 pimNeighbors.remove(srcip, nbr);
309 return;
310 } else {
311 // Neighbor has changed one of their options.
312 pimNeighbors.put(srcip, newNbr);
313 nbr = newNbr;
Rusty Eddy390498d2016-01-15 19:21:32 -0800314 }
Rusty Eddy95421642015-10-21 17:22:13 -0700315 }
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800316
Jonathan Hart54119bb2016-02-06 18:48:27 -0800317 // Refresh this neighbor's timestamp
Rusty Eddy390498d2016-01-15 19:21:32 -0800318 nbr.refreshTimestamp();
319
320 /*
Jonathan Hart5af5f142016-01-28 18:45:27 -0800321 * the election method will first determine if an election
Rusty Eddy390498d2016-01-15 19:21:32 -0800322 * needs to be run, if so it will run the election. The
323 * IP address of the DR will be returned. If the IP address
324 * of the DR is different from what we already have we know a
325 * new DR has been elected.
326 */
327 IpAddress electedIp = election(nbr, drip, drpri);
328 if (!drip.equals(electedIp)) {
329 // we have a new DR.
330 drIpaddress = electedIp;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800331 }
Rusty Eddy95421642015-10-21 17:22:13 -0700332 }
333
Rusty Eddy390498d2016-01-15 19:21:32 -0800334 // Run an election if we need to. Return the elected IP address.
Jonathan Hart5af5f142016-01-28 18:45:27 -0800335 private IpAddress election(PIMNeighbor nbr, IpAddress drIp, int drPriority) {
Rusty Eddy390498d2016-01-15 19:21:32 -0800336
Jonathan Hart54119bb2016-02-06 18:48:27 -0800337 IpAddress nbrIp = nbr.ipAddress();
338 if (nbr.priority() > drPriority) {
Jonathan Hart5af5f142016-01-28 18:45:27 -0800339 return nbrIp;
Rusty Eddy390498d2016-01-15 19:21:32 -0800340 }
341
Jonathan Hart5af5f142016-01-28 18:45:27 -0800342 if (nbrIp.compareTo(drIp) > 0) {
343 return nbrIp;
Rusty Eddy390498d2016-01-15 19:21:32 -0800344 }
Jonathan Hart5af5f142016-01-28 18:45:27 -0800345 return drIp;
Rusty Eddy390498d2016-01-15 19:21:32 -0800346 }
347
Rusty Eddy95421642015-10-21 17:22:13 -0700348 /**
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800349 * Process an incoming PIM JoinPrune message.
Rusty Eddy95421642015-10-21 17:22:13 -0700350 *
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800351 * @param ethPkt the Ethernet packet header.
Rusty Eddy95421642015-10-21 17:22:13 -0700352 */
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800353 public void processJoinPrune(Ethernet ethPkt) {
Rusty Eddybcad55b2016-02-11 18:56:09 -0800354
355 IPv4 ip = (IPv4) ethPkt.getPayload();
356 checkNotNull(ip);
357
358 PIM pim = (PIM) ip.getPayload();
359 checkNotNull(pim);
360
361 PIMJoinPrune jpHdr = (PIMJoinPrune) pim.getPayload();
362 checkNotNull(jpHdr);
363
364 /*
365 * The Join/Prune messages are grouped by Group address. We'll walk each group address
366 * where we will possibly have to walk a list of source address for the joins and prunes.
367 */
368 Collection<PIMJoinPruneGroup> jpgs = jpHdr.getJoinPrunes();
369 for (PIMJoinPruneGroup jpg : jpgs) {
370 IpPrefix gpfx = jpg.getGroup();
371
372 // Walk the joins first.
373 for (IpPrefix spfx : jpg.getJoins().values()) {
374
375 // We may need
376
377
378 }
379
380 for (IpPrefix spfx : jpg.getPrunes().values()) {
381
382 // TODO: this is where we many need to remove multi-cast state and possibly intents.
383
384 }
385 }
386
Rusty Eddy95421642015-10-21 17:22:13 -0700387 }
Jonathan Hart5af5f142016-01-28 18:45:27 -0800388
389 /**
390 * Returns a builder for a PIM interface.
391 *
392 * @return PIM interface builder
393 */
394 public static Builder builder() {
395 return new Builder();
396 }
397
398 /**
399 * Builder for a PIM interface.
400 */
401 public static class Builder {
402 private Interface intf;
403 private PacketService packetService;
404 private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
405 private int priority = PIMHelloOption.DEFAULT_PRIORITY;
406 private short propagationDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
407 private short overrideInterval = PIMHelloOption.DEFAULT_OVERRIDEINTERVAL;
408
409 /**
410 * Uses the specified ONOS interface.
411 *
412 * @param intf ONOS interface
413 * @return this PIM interface builder
414 */
415 public Builder withInterface(Interface intf) {
416 this.intf = checkNotNull(intf);
417 return this;
418 }
419
420 /**
421 * Sets the reference to the packet service.
422 *
423 * @param packetService packet service
424 * @return this PIM interface builder
425 */
426 public Builder withPacketService(PacketService packetService) {
427 this.packetService = checkNotNull(packetService);
428 return this;
429 }
430
431 /**
432 * Uses the specified hold time.
433 *
434 * @param holdTime hold time in seconds
435 * @return this PIM interface builder
436 */
437 public Builder withHoldTime(short holdTime) {
438 this.holdtime = holdTime;
439 return this;
440 }
441
442 /**
443 * Uses the specified DR priority.
444 *
445 * @param priority DR priority
446 * @return this PIM interface builder
447 */
448 public Builder withPriority(int priority) {
449 this.priority = priority;
450 return this;
451 }
452
453 /**
454 * Uses the specified propagation delay.
455 *
456 * @param propagationDelay propagation delay in ms
457 * @return this PIM interface builder
458 */
459 public Builder withPropagationDelay(short propagationDelay) {
460 this.propagationDelay = propagationDelay;
461 return this;
462 }
463
464 /**
465 * Uses the specified override interval.
466 *
467 * @param overrideInterval override interval in ms
468 * @return this PIM interface builder
469 */
470 public Builder withOverrideInterval(short overrideInterval) {
471 this.overrideInterval = overrideInterval;
472 return this;
473 }
474
475 /**
476 * Builds the PIM interface.
477 *
478 * @return PIM interface
479 */
480 public PIMInterface build() {
481 checkArgument(intf != null, "Must provide an interface");
482 checkArgument(packetService != null, "Must provide a packet service");
483
484 return new PIMInterface(intf, holdtime, priority, propagationDelay,
485 overrideInterval, packetService);
486 }
487
488 }
Rusty Eddy95421642015-10-21 17:22:13 -0700489}