Committed by
Gerrit Code Review
Refactor ProxyManager Tests and added functionality to manage traffic coming and…
… going through vlan interfaces Change-Id: I8d748c42b48d0956c670be12ff2742cb2022fa62
Showing
2 changed files
with
86 additions
and
6 deletions
... | @@ -53,6 +53,7 @@ import org.slf4j.Logger; | ... | @@ -53,6 +53,7 @@ import org.slf4j.Logger; |
53 | 53 | ||
54 | import java.nio.ByteBuffer; | 54 | import java.nio.ByteBuffer; |
55 | import java.util.Set; | 55 | import java.util.Set; |
56 | +import java.util.stream.Collectors; | ||
56 | 57 | ||
57 | import static com.google.common.base.Preconditions.checkArgument; | 58 | import static com.google.common.base.Preconditions.checkArgument; |
58 | import static com.google.common.base.Preconditions.checkNotNull; | 59 | import static com.google.common.base.Preconditions.checkNotNull; |
... | @@ -199,11 +200,49 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -199,11 +200,49 @@ public class ProxyArpManager implements ProxyArpService { |
199 | return; | 200 | return; |
200 | } | 201 | } |
201 | 202 | ||
203 | + // If the packets has a vlanId look if there are some other | ||
204 | + // interfaces in the configuration on the same vlan and broadcast | ||
205 | + // the packet out just of through those interfaces. | ||
206 | + VlanId vlanId = context.vlan(); | ||
207 | + | ||
208 | + Set<Interface> filteredVlanInterfaces = | ||
209 | + filterVlanInterfacesNoIp(interfaceService.getInterfacesByVlan(vlanId)); | ||
210 | + | ||
211 | + if (vlanId != null | ||
212 | + && !vlanId.equals(VlanId.NONE) | ||
213 | + && confContainsVlans(vlanId, context.inPort())) { | ||
214 | + vlanFlood(context.packet(), filteredVlanInterfaces, context.inPort); | ||
215 | + return; | ||
216 | + } | ||
217 | + | ||
202 | // The request couldn't be resolved. | 218 | // The request couldn't be resolved. |
203 | // Flood the request on all ports except the incoming port. | 219 | // Flood the request on all ports except the incoming port. |
204 | flood(context.packet(), context.inPort()); | 220 | flood(context.packet(), context.inPort()); |
205 | } | 221 | } |
206 | 222 | ||
223 | + private Set<Interface> filterVlanInterfacesNoIp(Set<Interface> vlanInterfaces) { | ||
224 | + return vlanInterfaces | ||
225 | + .stream() | ||
226 | + .filter(intf -> intf.ipAddresses().isEmpty()) | ||
227 | + .collect(Collectors.toSet()); | ||
228 | + } | ||
229 | + | ||
230 | + /** | ||
231 | + * States if the interface configuration contains more than one interface configured | ||
232 | + * on a specific vlan, including the interface passed as argument. | ||
233 | + * | ||
234 | + * @param vlanId the vlanid to look for in the interface configuration | ||
235 | + * @param connectPoint the connect point to exclude from the search | ||
236 | + * @return true if interfaces are found. False otherwise | ||
237 | + */ | ||
238 | + private boolean confContainsVlans(VlanId vlanId, ConnectPoint connectPoint) { | ||
239 | + Set<Interface> vlanInterfaces = interfaceService.getInterfacesByVlan(vlanId); | ||
240 | + return interfaceService.getInterfacesByVlan(vlanId) | ||
241 | + .stream() | ||
242 | + .anyMatch(intf -> intf.connectPoint().equals(connectPoint) && intf.ipAddresses().isEmpty()) | ||
243 | + && vlanInterfaces.size() > 1; | ||
244 | + } | ||
245 | + | ||
207 | /** | 246 | /** |
208 | * Builds and sends a reply message given a request context and the resolved | 247 | * Builds and sends a reply message given a request context and the resolved |
209 | * MAC address to answer with. | 248 | * MAC address to answer with. |
... | @@ -259,14 +298,29 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -259,14 +298,29 @@ public class ProxyArpManager implements ProxyArpService { |
259 | /** | 298 | /** |
260 | * Returns whether the given port has any IP addresses configured or not. | 299 | * Returns whether the given port has any IP addresses configured or not. |
261 | * | 300 | * |
262 | - * @param port the port to check | 301 | + * @param connectPoint the port to check |
263 | * @return true if the port has at least one IP address configured, | 302 | * @return true if the port has at least one IP address configured, |
264 | - * otherwise false | 303 | + * false otherwise |
304 | + */ | ||
305 | + private boolean hasIpAddress(ConnectPoint connectPoint) { | ||
306 | + return interfaceService.getInterfacesByPort(connectPoint) | ||
307 | + .stream() | ||
308 | + .flatMap(intf -> intf.ipAddresses().stream()) | ||
309 | + .findAny() | ||
310 | + .isPresent(); | ||
311 | + } | ||
312 | + | ||
313 | + /** | ||
314 | + * Returns whether the given port has any VLAN configured or not. | ||
315 | + * | ||
316 | + * @param connectPoint the port to check | ||
317 | + * @return true if the port has at least one VLAN configured, | ||
318 | + * false otherwise | ||
265 | */ | 319 | */ |
266 | - private boolean hasIpAddress(ConnectPoint port) { | 320 | + private boolean hasVlan(ConnectPoint connectPoint) { |
267 | - return interfaceService.getInterfacesByPort(port) | 321 | + return interfaceService.getInterfacesByPort(connectPoint) |
268 | .stream() | 322 | .stream() |
269 | - .map(intf -> intf.ipAddresses()) | 323 | + .filter(intf -> !intf.vlan().equals(VlanId.NONE)) |
270 | .findAny() | 324 | .findAny() |
271 | .isPresent(); | 325 | .isPresent(); |
272 | } | 326 | } |
... | @@ -322,6 +376,30 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -322,6 +376,30 @@ public class ProxyArpManager implements ProxyArpService { |
322 | } | 376 | } |
323 | 377 | ||
324 | /** | 378 | /** |
379 | + * Flood the arp request at all edges on a specifc VLAN. | ||
380 | + * | ||
381 | + * @param request the arp request | ||
382 | + * @param dsts the destination interfaces | ||
383 | + * @param inPort the connect point the arp request was received on | ||
384 | + */ | ||
385 | + private void vlanFlood(Ethernet request, Set<Interface> dsts, ConnectPoint inPort) { | ||
386 | + TrafficTreatment.Builder builder = null; | ||
387 | + ByteBuffer buf = ByteBuffer.wrap(request.serialize()); | ||
388 | + | ||
389 | + for (Interface intf : dsts) { | ||
390 | + ConnectPoint cPoint = intf.connectPoint(); | ||
391 | + if (cPoint.equals(inPort)) { | ||
392 | + continue; | ||
393 | + } | ||
394 | + | ||
395 | + builder = DefaultTrafficTreatment.builder(); | ||
396 | + builder.setOutput(cPoint.port()); | ||
397 | + packetService.emit(new DefaultOutboundPacket(cPoint.deviceId(), | ||
398 | + builder.build(), buf)); | ||
399 | + } | ||
400 | + } | ||
401 | + | ||
402 | + /** | ||
325 | * Flood the arp request at all edges in the network. | 403 | * Flood the arp request at all edges in the network. |
326 | * | 404 | * |
327 | * @param request the arp request | 405 | * @param request the arp request |
... | @@ -332,7 +410,9 @@ public class ProxyArpManager implements ProxyArpService { | ... | @@ -332,7 +410,9 @@ public class ProxyArpManager implements ProxyArpService { |
332 | ByteBuffer buf = ByteBuffer.wrap(request.serialize()); | 410 | ByteBuffer buf = ByteBuffer.wrap(request.serialize()); |
333 | 411 | ||
334 | for (ConnectPoint connectPoint : edgeService.getEdgePoints()) { | 412 | for (ConnectPoint connectPoint : edgeService.getEdgePoints()) { |
335 | - if (hasIpAddress(connectPoint) || connectPoint.equals(inPort)) { | 413 | + if (hasIpAddress(connectPoint) |
414 | + || hasVlan(connectPoint) | ||
415 | + || connectPoint.equals(inPort)) { | ||
336 | continue; | 416 | continue; |
337 | } | 417 | } |
338 | 418 | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment