Jonathan Hart
Committed by Gerrit Code Review

Make PIM hello interval configurable on a per-interface basis.

Change-Id: I7a0788be4445c7befbd947a3df893bcce1118bf5
...@@ -40,6 +40,7 @@ import java.util.HashMap; ...@@ -40,6 +40,7 @@ import java.util.HashMap;
40 import java.util.Map; 40 import java.util.Map;
41 import java.util.Random; 41 import java.util.Random;
42 import java.util.Set; 42 import java.util.Set;
43 +import java.util.concurrent.TimeUnit;
43 import java.util.stream.Collectors; 44 import java.util.stream.Collectors;
44 45
45 import static com.google.common.base.Preconditions.checkArgument; 46 import static com.google.common.base.Preconditions.checkArgument;
...@@ -68,6 +69,10 @@ public final class PIMInterface { ...@@ -68,6 +69,10 @@ public final class PIMInterface {
68 // Neighbor priority 69 // Neighbor priority
69 private int priority = PIMHelloOption.DEFAULT_PRIORITY; 70 private int priority = PIMHelloOption.DEFAULT_PRIORITY;
70 71
72 + private final int helloInterval;
73 +
74 + private long lastHello;
75 +
71 // Our current genid 76 // Our current genid
72 private final int generationId; 77 private final int generationId;
73 78
...@@ -88,19 +93,23 @@ public final class PIMInterface { ...@@ -88,19 +93,23 @@ public final class PIMInterface {
88 * @param packetService reference to the packet service 93 * @param packetService reference to the packet service
89 */ 94 */
90 private PIMInterface(Interface intf, 95 private PIMInterface(Interface intf,
91 - short holdTime, 96 + int helloInterval,
92 - int priority, 97 + short holdTime,
93 - short propagationDelay, 98 + int priority,
94 - short overrideInterval, 99 + short propagationDelay,
95 - PacketService packetService) { 100 + short overrideInterval,
101 + PacketService packetService) {
96 102
97 onosInterface = intf; 103 onosInterface = intf;
98 outputTreatment = createOutputTreatment(); 104 outputTreatment = createOutputTreatment();
105 + this.helloInterval = helloInterval;
99 this.holdtime = holdTime; 106 this.holdtime = holdTime;
100 this.packetService = packetService; 107 this.packetService = packetService;
101 IpAddress ourIp = getIpAddress(); 108 IpAddress ourIp = getIpAddress();
102 MacAddress mac = intf.mac(); 109 MacAddress mac = intf.mac();
103 110
111 + lastHello = 0;
112 +
104 generationId = new Random().nextInt(); 113 generationId = new Random().nextInt();
105 114
106 // Create a PIM Neighbor to represent ourselves for DR election. 115 // Create a PIM Neighbor to represent ourselves for DR election.
...@@ -232,6 +241,13 @@ public final class PIMInterface { ...@@ -232,6 +241,13 @@ public final class PIMInterface {
232 * result of a newly created interface. 241 * result of a newly created interface.
233 */ 242 */
234 public void sendHello() { 243 public void sendHello() {
244 + if (lastHello + TimeUnit.SECONDS.toMillis(helloInterval) >
245 + System.currentTimeMillis()) {
246 + return;
247 + }
248 +
249 + lastHello = System.currentTimeMillis();
250 +
235 // Create the base PIM Packet and mark it a hello packet 251 // Create the base PIM Packet and mark it a hello packet
236 PIMPacket pimPacket = new PIMPacket(PIM.TYPE_HELLO); 252 PIMPacket pimPacket = new PIMPacket(PIM.TYPE_HELLO);
237 253
...@@ -401,6 +417,7 @@ public final class PIMInterface { ...@@ -401,6 +417,7 @@ public final class PIMInterface {
401 public static class Builder { 417 public static class Builder {
402 private Interface intf; 418 private Interface intf;
403 private PacketService packetService; 419 private PacketService packetService;
420 + private int helloInterval = PIMInterfaceManager.DEFAULT_HELLO_INTERVAL;
404 private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME; 421 private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
405 private int priority = PIMHelloOption.DEFAULT_PRIORITY; 422 private int priority = PIMHelloOption.DEFAULT_PRIORITY;
406 private short propagationDelay = PIMHelloOption.DEFAULT_PRUNEDELAY; 423 private short propagationDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
...@@ -429,6 +446,17 @@ public final class PIMInterface { ...@@ -429,6 +446,17 @@ public final class PIMInterface {
429 } 446 }
430 447
431 /** 448 /**
449 + * 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 + /**
432 * Uses the specified hold time. 460 * Uses the specified hold time.
433 * 461 *
434 * @param holdTime hold time in seconds 462 * @param holdTime hold time in seconds
...@@ -481,8 +509,8 @@ public final class PIMInterface { ...@@ -481,8 +509,8 @@ public final class PIMInterface {
481 checkArgument(intf != null, "Must provide an interface"); 509 checkArgument(intf != null, "Must provide an interface");
482 checkArgument(packetService != null, "Must provide a packet service"); 510 checkArgument(packetService != null, "Must provide a packet service");
483 511
484 - return new PIMInterface(intf, holdtime, priority, propagationDelay, 512 + return new PIMInterface(intf, helloInterval, holdtime, priority,
485 - overrideInterval, packetService); 513 + propagationDelay, overrideInterval, packetService);
486 } 514 }
487 515
488 } 516 }
......
...@@ -59,20 +59,19 @@ public class PIMInterfaceManager implements PIMInterfaceService { ...@@ -59,20 +59,19 @@ public class PIMInterfaceManager implements PIMInterfaceService {
59 private static final Class<PimInterfaceConfig> PIM_INTERFACE_CONFIG_CLASS = PimInterfaceConfig.class; 59 private static final Class<PimInterfaceConfig> PIM_INTERFACE_CONFIG_CLASS = PimInterfaceConfig.class;
60 private static final String PIM_INTERFACE_CONFIG_KEY = "pimInterface"; 60 private static final String PIM_INTERFACE_CONFIG_KEY = "pimInterface";
61 61
62 - private static final int DEFAULT_TIMEOUT_TASK_PERIOD_MS = 250; 62 + public static final int DEFAULT_HELLO_INTERVAL = 30; // seconds
63 +
64 + private static final int DEFAULT_TASK_PERIOD_MS = 250;
63 65
64 // Create a Scheduled Executor service for recurring tasks 66 // Create a Scheduled Executor service for recurring tasks
65 private final ScheduledExecutorService scheduledExecutorService = 67 private final ScheduledExecutorService scheduledExecutorService =
66 Executors.newScheduledThreadPool(1); 68 Executors.newScheduledThreadPool(1);
67 69
68 - // Wait for a bout 3 seconds before sending the initial hello messages. 70 + private final long initialHelloDelay = 1000;
69 - // TODO: make this tunnable.
70 - private final long initialHelloDelay = 3;
71 71
72 - // Send PIM hello packets: 30 seconds. 72 + private final long pimHelloPeriod = DEFAULT_TASK_PERIOD_MS;
73 - private final long pimHelloPeriod = 30;
74 73
75 - private final int timeoutTaskPeriod = DEFAULT_TIMEOUT_TASK_PERIOD_MS; 74 + private final int timeoutTaskPeriod = DEFAULT_TASK_PERIOD_MS;
76 75
77 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 76 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78 protected PacketService packetService; 77 protected PacketService packetService;
...@@ -121,7 +120,7 @@ public class PIMInterfaceManager implements PIMInterfaceService { ...@@ -121,7 +120,7 @@ public class PIMInterfaceManager implements PIMInterfaceService {
121 scheduledExecutorService.scheduleAtFixedRate( 120 scheduledExecutorService.scheduleAtFixedRate(
122 SafeRecurringTask.wrap( 121 SafeRecurringTask.wrap(
123 () -> pimInterfaces.values().forEach(PIMInterface::sendHello)), 122 () -> pimInterfaces.values().forEach(PIMInterface::sendHello)),
124 - initialHelloDelay, pimHelloPeriod, TimeUnit.SECONDS); 123 + initialHelloDelay, pimHelloPeriod, TimeUnit.MILLISECONDS);
125 124
126 // Schedule task to periodically time out expired neighbors 125 // Schedule task to periodically time out expired neighbors
127 scheduledExecutorService.scheduleAtFixedRate( 126 scheduledExecutorService.scheduleAtFixedRate(
...@@ -194,6 +193,9 @@ public class PIMInterfaceManager implements PIMInterfaceService { ...@@ -194,6 +193,9 @@ public class PIMInterfaceManager implements PIMInterfaceService {
194 .withPacketService(packetService) 193 .withPacketService(packetService)
195 .withInterface(intf); 194 .withInterface(intf);
196 195
196 + if (config.getHelloInterval().isPresent()) {
197 + builder.withHelloInterval(config.getHelloInterval().get());
198 + }
197 if (config.getHoldTime().isPresent()) { 199 if (config.getHoldTime().isPresent()) {
198 builder.withHoldTime(config.getHoldTime().get()); 200 builder.withHoldTime(config.getHoldTime().get());
199 } 201 }
......
...@@ -28,6 +28,7 @@ public class PimInterfaceConfig extends Config<ConnectPoint> { ...@@ -28,6 +28,7 @@ public class PimInterfaceConfig extends Config<ConnectPoint> {
28 28
29 private static final String INTERFACE_NAME = "interfaceName"; 29 private static final String INTERFACE_NAME = "interfaceName";
30 private static final String ENABLED = "enabled"; 30 private static final String ENABLED = "enabled";
31 + private static final String HELLO_INTERVAL = "helloInterval";
31 private static final String HOLD_TIME = "holdTime"; 32 private static final String HOLD_TIME = "holdTime";
32 private static final String PRIORITY = "priority"; 33 private static final String PRIORITY = "priority";
33 private static final String PROPAGATION_DELAY = "propagationDelay"; 34 private static final String PROPAGATION_DELAY = "propagationDelay";
...@@ -53,6 +54,18 @@ public class PimInterfaceConfig extends Config<ConnectPoint> { ...@@ -53,6 +54,18 @@ public class PimInterfaceConfig extends Config<ConnectPoint> {
53 } 54 }
54 55
55 /** 56 /**
57 + * Gets the hello interval of the interface.
58 + *
59 + * @return hello interval
60 + */
61 + public Optional<Integer> getHelloInterval() {
62 + if (node.path(HELLO_INTERVAL).isMissingNode()) {
63 + return Optional.empty();
64 + }
65 + return Optional.of(Integer.parseInt(node.path(HELLO_INTERVAL).asText()));
66 + }
67 +
68 + /**
56 * Gets the HELLO hold time of the interface. 69 * Gets the HELLO hold time of the interface.
57 * 70 *
58 * @return hold time 71 * @return hold time
......