Control plane redirect for OSPF traffic
Change-Id: I1d31bceadce6f67070a14afaaebdeab07d16f40a
Showing
2 changed files
with
81 additions
and
22 deletions
| ... | @@ -25,7 +25,9 @@ import org.onosproject.net.config.Config; | ... | @@ -25,7 +25,9 @@ import org.onosproject.net.config.Config; |
| 25 | */ | 25 | */ |
| 26 | public class RouterConfig extends Config<ApplicationId> { | 26 | public class RouterConfig extends Config<ApplicationId> { |
| 27 | 27 | ||
| 28 | - public static final String CP_CONNECT_POINT = "controlPlaneConnectPoint"; | 28 | + private static final String CP_CONNECT_POINT = "controlPlaneConnectPoint"; |
| 29 | + private static final String OSPF_ENABLED = "ospfEnabled"; | ||
| 30 | + private static final String PIM_ENABLED = "pimEnabled"; | ||
| 29 | 31 | ||
| 30 | /** | 32 | /** |
| 31 | * Returns the routing control plane connect point. | 33 | * Returns the routing control plane connect point. |
| ... | @@ -35,4 +37,22 @@ public class RouterConfig extends Config<ApplicationId> { | ... | @@ -35,4 +37,22 @@ public class RouterConfig extends Config<ApplicationId> { |
| 35 | public ConnectPoint getControlPlaneConnectPoint() { | 37 | public ConnectPoint getControlPlaneConnectPoint() { |
| 36 | return ConnectPoint.deviceConnectPoint(object.path(CP_CONNECT_POINT).asText()); | 38 | return ConnectPoint.deviceConnectPoint(object.path(CP_CONNECT_POINT).asText()); |
| 37 | } | 39 | } |
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * Returns whether OSPF is enabled on this router. | ||
| 43 | + * | ||
| 44 | + * @return true if OSPF is enabled, otherwise false | ||
| 45 | + */ | ||
| 46 | + public boolean getOspfEnabled() { | ||
| 47 | + return object.path(OSPF_ENABLED).asBoolean(false); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * Returns whether PIM is enabled on this router. | ||
| 52 | + * | ||
| 53 | + * @return true if PIM is enabled, otherwise false | ||
| 54 | + */ | ||
| 55 | + public boolean pimEnabled() { | ||
| 56 | + return object.path(PIM_ENABLED).asBoolean(false); | ||
| 57 | + } | ||
| 38 | } | 58 | } | ... | ... |
| ... | @@ -59,11 +59,13 @@ public class ControlPlaneRedirectManager { | ... | @@ -59,11 +59,13 @@ public class ControlPlaneRedirectManager { |
| 59 | private final Logger log = getLogger(getClass()); | 59 | private final Logger log = getLogger(getClass()); |
| 60 | 60 | ||
| 61 | private static final int PRIORITY = 40001; | 61 | private static final int PRIORITY = 40001; |
| 62 | + private static final int OSPF_IP_PROTO = 0x59; | ||
| 62 | 63 | ||
| 63 | private static final String APP_NAME = "org.onosproject.cpredirect"; | 64 | private static final String APP_NAME = "org.onosproject.cpredirect"; |
| 64 | private ApplicationId appId; | 65 | private ApplicationId appId; |
| 65 | 66 | ||
| 66 | private ConnectPoint controlPlaneConnectPoint; | 67 | private ConnectPoint controlPlaneConnectPoint; |
| 68 | + private boolean ospfEnabled = false; | ||
| 67 | 69 | ||
| 68 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 70 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 69 | protected CoreService coreService; | 71 | protected CoreService coreService; |
| ... | @@ -112,27 +114,31 @@ public class ControlPlaneRedirectManager { | ... | @@ -112,27 +114,31 @@ public class ControlPlaneRedirectManager { |
| 112 | return; | 114 | return; |
| 113 | } | 115 | } |
| 114 | 116 | ||
| 115 | - if (!config.getControlPlaneConnectPoint().equals(controlPlaneConnectPoint)) { | 117 | + controlPlaneConnectPoint = config.getControlPlaneConnectPoint(); |
| 116 | - this.controlPlaneConnectPoint = config.getControlPlaneConnectPoint(); | 118 | + ospfEnabled = config.getOspfEnabled(); |
| 119 | + | ||
| 120 | + updateDevice(); | ||
| 117 | } | 121 | } |
| 118 | 122 | ||
| 123 | + private void updateDevice() { | ||
| 119 | if (controlPlaneConnectPoint != null && | 124 | if (controlPlaneConnectPoint != null && |
| 120 | deviceService.isAvailable(controlPlaneConnectPoint.deviceId())) { | 125 | deviceService.isAvailable(controlPlaneConnectPoint.deviceId())) { |
| 121 | - notifySwitchAvailable(); | ||
| 122 | - } | ||
| 123 | - } | ||
| 124 | - | ||
| 125 | - private void notifySwitchAvailable() { | ||
| 126 | DeviceId deviceId = controlPlaneConnectPoint.deviceId(); | 126 | DeviceId deviceId = controlPlaneConnectPoint.deviceId(); |
| 127 | 127 | ||
| 128 | interfaceService.getInterfaces().stream() | 128 | interfaceService.getInterfaces().stream() |
| 129 | .filter(intf -> intf.connectPoint().deviceId().equals(deviceId)) | 129 | .filter(intf -> intf.connectPoint().deviceId().equals(deviceId)) |
| 130 | - .forEach(this::addInterfaceForwarding); | 130 | + .forEach(this::provisionInterface); |
| 131 | + | ||
| 132 | + log.info("Set up interfaces on {}", controlPlaneConnectPoint.deviceId()); | ||
| 133 | + } | ||
| 134 | + } | ||
| 131 | 135 | ||
| 132 | - log.info("Sent interface objectives to {}", controlPlaneConnectPoint.deviceId()); | 136 | + private void provisionInterface(Interface intf) { |
| 137 | + addBasicInterfaceForwarding(intf); | ||
| 138 | + updateOspfForwarding(intf); | ||
| 133 | } | 139 | } |
| 134 | 140 | ||
| 135 | - private void addInterfaceForwarding(Interface intf) { | 141 | + private void addBasicInterfaceForwarding(Interface intf) { |
| 136 | log.debug("Adding interface objectives for {}", intf); | 142 | log.debug("Adding interface objectives for {}", intf); |
| 137 | 143 | ||
| 138 | DeviceId deviceId = controlPlaneConnectPoint.deviceId(); | 144 | DeviceId deviceId = controlPlaneConnectPoint.deviceId(); |
| ... | @@ -153,7 +159,7 @@ public class ControlPlaneRedirectManager { | ... | @@ -153,7 +159,7 @@ public class ControlPlaneRedirectManager { |
| 153 | .build(); | 159 | .build(); |
| 154 | 160 | ||
| 155 | flowObjectiveService.forward(deviceId, | 161 | flowObjectiveService.forward(deviceId, |
| 156 | - buildForwardingObjective(toSelector, toTreatment)); | 162 | + buildForwardingObjective(toSelector, toTreatment, true)); |
| 157 | 163 | ||
| 158 | // IPv4 from router | 164 | // IPv4 from router |
| 159 | TrafficSelector fromSelector = DefaultTrafficSelector.builder() | 165 | TrafficSelector fromSelector = DefaultTrafficSelector.builder() |
| ... | @@ -169,8 +175,7 @@ public class ControlPlaneRedirectManager { | ... | @@ -169,8 +175,7 @@ public class ControlPlaneRedirectManager { |
| 169 | .build(); | 175 | .build(); |
| 170 | 176 | ||
| 171 | flowObjectiveService.forward(deviceId, | 177 | flowObjectiveService.forward(deviceId, |
| 172 | - buildForwardingObjective(fromSelector, intfTreatment)); | 178 | + buildForwardingObjective(fromSelector, intfTreatment, true)); |
| 173 | - | ||
| 174 | 179 | ||
| 175 | // ARP to router | 180 | // ARP to router |
| 176 | toSelector = DefaultTrafficSelector.builder() | 181 | toSelector = DefaultTrafficSelector.builder() |
| ... | @@ -185,7 +190,7 @@ public class ControlPlaneRedirectManager { | ... | @@ -185,7 +190,7 @@ public class ControlPlaneRedirectManager { |
| 185 | .build(); | 190 | .build(); |
| 186 | 191 | ||
| 187 | flowObjectiveService.forward(deviceId, | 192 | flowObjectiveService.forward(deviceId, |
| 188 | - buildForwardingObjective(toSelector, toTreatment)); | 193 | + buildForwardingObjective(toSelector, toTreatment, true)); |
| 189 | 194 | ||
| 190 | // ARP from router | 195 | // ARP from router |
| 191 | fromSelector = DefaultTrafficSelector.builder() | 196 | fromSelector = DefaultTrafficSelector.builder() |
| ... | @@ -201,22 +206,53 @@ public class ControlPlaneRedirectManager { | ... | @@ -201,22 +206,53 @@ public class ControlPlaneRedirectManager { |
| 201 | .build(); | 206 | .build(); |
| 202 | 207 | ||
| 203 | flowObjectiveService.forward(deviceId, | 208 | flowObjectiveService.forward(deviceId, |
| 204 | - buildForwardingObjective(fromSelector, intfTreatment)); | 209 | + buildForwardingObjective(fromSelector, intfTreatment, true)); |
| 210 | + } | ||
| 205 | } | 211 | } |
| 212 | + | ||
| 213 | + private void updateOspfForwarding(Interface intf) { | ||
| 214 | + // OSPF to router | ||
| 215 | + TrafficSelector toSelector = DefaultTrafficSelector.builder() | ||
| 216 | + .matchInPort(intf.connectPoint().port()) | ||
| 217 | + .matchEthType(EthType.EtherType.IPV4.ethType().toShort()) | ||
| 218 | + .matchVlanId(intf.vlan()) | ||
| 219 | + .matchIPProtocol((byte) OSPF_IP_PROTO) | ||
| 220 | + .build(); | ||
| 221 | + | ||
| 222 | + TrafficTreatment toTreatment = DefaultTrafficTreatment.builder() | ||
| 223 | + .setOutput(controlPlaneConnectPoint.port()) | ||
| 224 | + .build(); | ||
| 225 | + | ||
| 226 | + flowObjectiveService.forward(controlPlaneConnectPoint.deviceId(), | ||
| 227 | + buildForwardingObjective(toSelector, toTreatment, ospfEnabled)); | ||
| 206 | } | 228 | } |
| 207 | 229 | ||
| 230 | + /** | ||
| 231 | + * Builds a forwarding objective from the given selector and treatment. | ||
| 232 | + * | ||
| 233 | + * @param selector selector | ||
| 234 | + * @param treatment treatment | ||
| 235 | + * @param add true to create an add objective, false to create a remove | ||
| 236 | + * objective | ||
| 237 | + * @return forwarding objective | ||
| 238 | + */ | ||
| 208 | private ForwardingObjective buildForwardingObjective(TrafficSelector selector, | 239 | private ForwardingObjective buildForwardingObjective(TrafficSelector selector, |
| 209 | - TrafficTreatment treatment) { | 240 | + TrafficTreatment treatment, |
| 241 | + boolean add) { | ||
| 210 | 242 | ||
| 211 | - return DefaultForwardingObjective.builder() | 243 | + ForwardingObjective.Builder fobBuilder = DefaultForwardingObjective.builder() |
| 212 | .withSelector(selector) | 244 | .withSelector(selector) |
| 213 | .withTreatment(treatment) | 245 | .withTreatment(treatment) |
| 214 | .fromApp(appId) | 246 | .fromApp(appId) |
| 215 | .withPriority(PRIORITY) | 247 | .withPriority(PRIORITY) |
| 216 | - .withFlag(ForwardingObjective.Flag.VERSATILE) | 248 | + .withFlag(ForwardingObjective.Flag.VERSATILE); |
| 217 | - .add(); | 249 | + |
| 250 | + return add ? fobBuilder.add() : fobBuilder.remove(); | ||
| 218 | } | 251 | } |
| 219 | 252 | ||
| 253 | + /** | ||
| 254 | + * Listener for device events. | ||
| 255 | + */ | ||
| 220 | private class InternalDeviceListener implements DeviceListener { | 256 | private class InternalDeviceListener implements DeviceListener { |
| 221 | @Override | 257 | @Override |
| 222 | public void event(DeviceEvent event) { | 258 | public void event(DeviceEvent event) { |
| ... | @@ -227,7 +263,7 @@ public class ControlPlaneRedirectManager { | ... | @@ -227,7 +263,7 @@ public class ControlPlaneRedirectManager { |
| 227 | case DEVICE_AVAILABILITY_CHANGED: | 263 | case DEVICE_AVAILABILITY_CHANGED: |
| 228 | if (deviceService.isAvailable(event.subject().id())) { | 264 | if (deviceService.isAvailable(event.subject().id())) { |
| 229 | log.info("Device connected {}", event.subject().id()); | 265 | log.info("Device connected {}", event.subject().id()); |
| 230 | - notifySwitchAvailable(); | 266 | + updateDevice(); |
| 231 | } | 267 | } |
| 232 | 268 | ||
| 233 | break; | 269 | break; |
| ... | @@ -244,10 +280,13 @@ public class ControlPlaneRedirectManager { | ... | @@ -244,10 +280,13 @@ public class ControlPlaneRedirectManager { |
| 244 | } | 280 | } |
| 245 | } | 281 | } |
| 246 | 282 | ||
| 283 | + /** | ||
| 284 | + * Listener for network config events. | ||
| 285 | + */ | ||
| 247 | private class InternalNetworkConfigListener implements NetworkConfigListener { | 286 | private class InternalNetworkConfigListener implements NetworkConfigListener { |
| 248 | @Override | 287 | @Override |
| 249 | public void event(NetworkConfigEvent event) { | 288 | public void event(NetworkConfigEvent event) { |
| 250 | - if (event.subject().equals(RoutingService.ROUTER_CONFIG_CLASS)) { | 289 | + if (event.configClass().equals(RoutingService.ROUTER_CONFIG_CLASS)) { |
| 251 | switch (event.type()) { | 290 | switch (event.type()) { |
| 252 | case CONFIG_ADDED: | 291 | case CONFIG_ADDED: |
| 253 | case CONFIG_UPDATED: | 292 | case CONFIG_UPDATED: | ... | ... |
-
Please register or login to post a comment