Control plane redirect for OSPF traffic
Change-Id: I1d31bceadce6f67070a14afaaebdeab07d16f40a
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/config/RouterConfig.java b/apps/routing-api/src/main/java/org/onosproject/routing/config/RouterConfig.java
index 7bd2b99..cfe719d 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/config/RouterConfig.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/config/RouterConfig.java
@@ -25,7 +25,9 @@
*/
public class RouterConfig extends Config<ApplicationId> {
- public static final String CP_CONNECT_POINT = "controlPlaneConnectPoint";
+ private static final String CP_CONNECT_POINT = "controlPlaneConnectPoint";
+ private static final String OSPF_ENABLED = "ospfEnabled";
+ private static final String PIM_ENABLED = "pimEnabled";
/**
* Returns the routing control plane connect point.
@@ -35,4 +37,22 @@
public ConnectPoint getControlPlaneConnectPoint() {
return ConnectPoint.deviceConnectPoint(object.path(CP_CONNECT_POINT).asText());
}
+
+ /**
+ * Returns whether OSPF is enabled on this router.
+ *
+ * @return true if OSPF is enabled, otherwise false
+ */
+ public boolean getOspfEnabled() {
+ return object.path(OSPF_ENABLED).asBoolean(false);
+ }
+
+ /**
+ * Returns whether PIM is enabled on this router.
+ *
+ * @return true if PIM is enabled, otherwise false
+ */
+ public boolean pimEnabled() {
+ return object.path(PIM_ENABLED).asBoolean(false);
+ }
}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java b/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java
index c5e7142..2294435 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java
@@ -59,11 +59,13 @@
private final Logger log = getLogger(getClass());
private static final int PRIORITY = 40001;
+ private static final int OSPF_IP_PROTO = 0x59;
private static final String APP_NAME = "org.onosproject.cpredirect";
private ApplicationId appId;
private ConnectPoint controlPlaneConnectPoint;
+ private boolean ospfEnabled = false;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@@ -112,27 +114,31 @@
return;
}
- if (!config.getControlPlaneConnectPoint().equals(controlPlaneConnectPoint)) {
- this.controlPlaneConnectPoint = config.getControlPlaneConnectPoint();
- }
+ controlPlaneConnectPoint = config.getControlPlaneConnectPoint();
+ ospfEnabled = config.getOspfEnabled();
+ updateDevice();
+ }
+
+ private void updateDevice() {
if (controlPlaneConnectPoint != null &&
deviceService.isAvailable(controlPlaneConnectPoint.deviceId())) {
- notifySwitchAvailable();
+ DeviceId deviceId = controlPlaneConnectPoint.deviceId();
+
+ interfaceService.getInterfaces().stream()
+ .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
+ .forEach(this::provisionInterface);
+
+ log.info("Set up interfaces on {}", controlPlaneConnectPoint.deviceId());
}
}
- private void notifySwitchAvailable() {
- DeviceId deviceId = controlPlaneConnectPoint.deviceId();
-
- interfaceService.getInterfaces().stream()
- .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
- .forEach(this::addInterfaceForwarding);
-
- log.info("Sent interface objectives to {}", controlPlaneConnectPoint.deviceId());
+ private void provisionInterface(Interface intf) {
+ addBasicInterfaceForwarding(intf);
+ updateOspfForwarding(intf);
}
- private void addInterfaceForwarding(Interface intf) {
+ private void addBasicInterfaceForwarding(Interface intf) {
log.debug("Adding interface objectives for {}", intf);
DeviceId deviceId = controlPlaneConnectPoint.deviceId();
@@ -153,7 +159,7 @@
.build();
flowObjectiveService.forward(deviceId,
- buildForwardingObjective(toSelector, toTreatment));
+ buildForwardingObjective(toSelector, toTreatment, true));
// IPv4 from router
TrafficSelector fromSelector = DefaultTrafficSelector.builder()
@@ -169,8 +175,7 @@
.build();
flowObjectiveService.forward(deviceId,
- buildForwardingObjective(fromSelector, intfTreatment));
-
+ buildForwardingObjective(fromSelector, intfTreatment, true));
// ARP to router
toSelector = DefaultTrafficSelector.builder()
@@ -185,7 +190,7 @@
.build();
flowObjectiveService.forward(deviceId,
- buildForwardingObjective(toSelector, toTreatment));
+ buildForwardingObjective(toSelector, toTreatment, true));
// ARP from router
fromSelector = DefaultTrafficSelector.builder()
@@ -201,22 +206,53 @@
.build();
flowObjectiveService.forward(deviceId,
- buildForwardingObjective(fromSelector, intfTreatment));
+ buildForwardingObjective(fromSelector, intfTreatment, true));
}
}
- private ForwardingObjective buildForwardingObjective(TrafficSelector selector,
- TrafficTreatment treatment) {
+ private void updateOspfForwarding(Interface intf) {
+ // OSPF to router
+ TrafficSelector toSelector = DefaultTrafficSelector.builder()
+ .matchInPort(intf.connectPoint().port())
+ .matchEthType(EthType.EtherType.IPV4.ethType().toShort())
+ .matchVlanId(intf.vlan())
+ .matchIPProtocol((byte) OSPF_IP_PROTO)
+ .build();
- return DefaultForwardingObjective.builder()
+ TrafficTreatment toTreatment = DefaultTrafficTreatment.builder()
+ .setOutput(controlPlaneConnectPoint.port())
+ .build();
+
+ flowObjectiveService.forward(controlPlaneConnectPoint.deviceId(),
+ buildForwardingObjective(toSelector, toTreatment, ospfEnabled));
+ }
+
+ /**
+ * Builds a forwarding objective from the given selector and treatment.
+ *
+ * @param selector selector
+ * @param treatment treatment
+ * @param add true to create an add objective, false to create a remove
+ * objective
+ * @return forwarding objective
+ */
+ private ForwardingObjective buildForwardingObjective(TrafficSelector selector,
+ TrafficTreatment treatment,
+ boolean add) {
+
+ ForwardingObjective.Builder fobBuilder = DefaultForwardingObjective.builder()
.withSelector(selector)
.withTreatment(treatment)
.fromApp(appId)
.withPriority(PRIORITY)
- .withFlag(ForwardingObjective.Flag.VERSATILE)
- .add();
+ .withFlag(ForwardingObjective.Flag.VERSATILE);
+
+ return add ? fobBuilder.add() : fobBuilder.remove();
}
+ /**
+ * Listener for device events.
+ */
private class InternalDeviceListener implements DeviceListener {
@Override
public void event(DeviceEvent event) {
@@ -227,7 +263,7 @@
case DEVICE_AVAILABILITY_CHANGED:
if (deviceService.isAvailable(event.subject().id())) {
log.info("Device connected {}", event.subject().id());
- notifySwitchAvailable();
+ updateDevice();
}
break;
@@ -244,10 +280,13 @@
}
}
+ /**
+ * Listener for network config events.
+ */
private class InternalNetworkConfigListener implements NetworkConfigListener {
@Override
public void event(NetworkConfigEvent event) {
- if (event.subject().equals(RoutingService.ROUTER_CONFIG_CLASS)) {
+ if (event.configClass().equals(RoutingService.ROUTER_CONFIG_CLASS)) {
switch (event.type()) {
case CONFIG_ADDED:
case CONFIG_UPDATED: