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