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;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkArgument;
......@@ -68,6 +69,10 @@ public final class PIMInterface {
// Neighbor priority
private int priority = PIMHelloOption.DEFAULT_PRIORITY;
private final int helloInterval;
private long lastHello;
// Our current genid
private final int generationId;
......@@ -88,19 +93,23 @@ public final class PIMInterface {
* @param packetService reference to the packet service
*/
private PIMInterface(Interface intf,
short holdTime,
int priority,
short propagationDelay,
short overrideInterval,
PacketService packetService) {
int helloInterval,
short holdTime,
int priority,
short propagationDelay,
short overrideInterval,
PacketService packetService) {
onosInterface = intf;
outputTreatment = createOutputTreatment();
this.helloInterval = helloInterval;
this.holdtime = holdTime;
this.packetService = packetService;
IpAddress ourIp = getIpAddress();
MacAddress mac = intf.mac();
lastHello = 0;
generationId = new Random().nextInt();
// Create a PIM Neighbor to represent ourselves for DR election.
......@@ -232,6 +241,13 @@ public final class PIMInterface {
* result of a newly created interface.
*/
public void sendHello() {
if (lastHello + TimeUnit.SECONDS.toMillis(helloInterval) >
System.currentTimeMillis()) {
return;
}
lastHello = System.currentTimeMillis();
// Create the base PIM Packet and mark it a hello packet
PIMPacket pimPacket = new PIMPacket(PIM.TYPE_HELLO);
......@@ -401,6 +417,7 @@ public final class PIMInterface {
public static class Builder {
private Interface intf;
private PacketService packetService;
private int helloInterval = PIMInterfaceManager.DEFAULT_HELLO_INTERVAL;
private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
private int priority = PIMHelloOption.DEFAULT_PRIORITY;
private short propagationDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
......@@ -429,6 +446,17 @@ public final class PIMInterface {
}
/**
* Users the specified hello interval.
*
* @param helloInterval hello interval in seconds
* @return this PIM interface builder
*/
public Builder withHelloInterval(int helloInterval) {
this.helloInterval = helloInterval;
return this;
}
/**
* Uses the specified hold time.
*
* @param holdTime hold time in seconds
......@@ -481,8 +509,8 @@ public final class PIMInterface {
checkArgument(intf != null, "Must provide an interface");
checkArgument(packetService != null, "Must provide a packet service");
return new PIMInterface(intf, holdtime, priority, propagationDelay,
overrideInterval, packetService);
return new PIMInterface(intf, helloInterval, holdtime, priority,
propagationDelay, overrideInterval, packetService);
}
}
......
......@@ -59,20 +59,19 @@ public class PIMInterfaceManager implements PIMInterfaceService {
private static final Class<PimInterfaceConfig> PIM_INTERFACE_CONFIG_CLASS = PimInterfaceConfig.class;
private static final String PIM_INTERFACE_CONFIG_KEY = "pimInterface";
private static final int DEFAULT_TIMEOUT_TASK_PERIOD_MS = 250;
public static final int DEFAULT_HELLO_INTERVAL = 30; // seconds
private static final int DEFAULT_TASK_PERIOD_MS = 250;
// Create a Scheduled Executor service for recurring tasks
private final ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(1);
// Wait for a bout 3 seconds before sending the initial hello messages.
// TODO: make this tunnable.
private final long initialHelloDelay = 3;
private final long initialHelloDelay = 1000;
// Send PIM hello packets: 30 seconds.
private final long pimHelloPeriod = 30;
private final long pimHelloPeriod = DEFAULT_TASK_PERIOD_MS;
private final int timeoutTaskPeriod = DEFAULT_TIMEOUT_TASK_PERIOD_MS;
private final int timeoutTaskPeriod = DEFAULT_TASK_PERIOD_MS;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
......@@ -121,7 +120,7 @@ public class PIMInterfaceManager implements PIMInterfaceService {
scheduledExecutorService.scheduleAtFixedRate(
SafeRecurringTask.wrap(
() -> pimInterfaces.values().forEach(PIMInterface::sendHello)),
initialHelloDelay, pimHelloPeriod, TimeUnit.SECONDS);
initialHelloDelay, pimHelloPeriod, TimeUnit.MILLISECONDS);
// Schedule task to periodically time out expired neighbors
scheduledExecutorService.scheduleAtFixedRate(
......@@ -194,6 +193,9 @@ public class PIMInterfaceManager implements PIMInterfaceService {
.withPacketService(packetService)
.withInterface(intf);
if (config.getHelloInterval().isPresent()) {
builder.withHelloInterval(config.getHelloInterval().get());
}
if (config.getHoldTime().isPresent()) {
builder.withHoldTime(config.getHoldTime().get());
}
......
......@@ -28,6 +28,7 @@ public class PimInterfaceConfig extends Config<ConnectPoint> {
private static final String INTERFACE_NAME = "interfaceName";
private static final String ENABLED = "enabled";
private static final String HELLO_INTERVAL = "helloInterval";
private static final String HOLD_TIME = "holdTime";
private static final String PRIORITY = "priority";
private static final String PROPAGATION_DELAY = "propagationDelay";
......@@ -53,6 +54,18 @@ public class PimInterfaceConfig extends Config<ConnectPoint> {
}
/**
* Gets the hello interval of the interface.
*
* @return hello interval
*/
public Optional<Integer> getHelloInterval() {
if (node.path(HELLO_INTERVAL).isMissingNode()) {
return Optional.empty();
}
return Optional.of(Integer.parseInt(node.path(HELLO_INTERVAL).asText()));
}
/**
* Gets the HELLO hold time of the interface.
*
* @return hold time
......