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