// Selects a path from the given set that does not lead back to the
 // specified port.
 private Path pickForwardPath(Set<Path> paths, PortNumber notToPort) {
   for (Path path : paths) {
     if (!path.src().port().equals(notToPort)) {
       return path;
     }
   }
   return null;
 }
Example #2
0
 /**
  * Creates a new point-to-point intent with the supplied ingress/egress ports and using the
  * specified explicit path.
  *
  * @param appId application identifier
  * @param selector traffic selector
  * @param treatment treatment
  * @param path traversed links
  * @param constraints optional list of constraints
  * @param priority priority to use for the generated flows
  * @throws NullPointerException {@code path} is null
  */
 protected PathIntent(
     ApplicationId appId,
     TrafficSelector selector,
     TrafficTreatment treatment,
     Path path,
     List<Constraint> constraints,
     int priority) {
   super(appId, null, resources(path.links()), selector, treatment, constraints, priority);
   PathIntent.validate(path.links());
   this.path = path;
 }
  @Override
  public boolean validate(Path path, LinkResourceService resourceService) {
    LinkedList<DeviceId> waypoints = new LinkedList<>(this.waypoints);
    DeviceId current = waypoints.poll();
    // This is safe because Path class ensures the number of links are more than 0
    Link firstLink = path.links().get(0);
    if (firstLink.src().elementId().equals(current)) {
      current = waypoints.poll();
    }

    for (Link link : path.links()) {
      if (link.dst().elementId().equals(current)) {
        current = waypoints.poll();
        // Empty waypoints means passing through all waypoints in the specified order
        if (current == null) {
          return true;
        }
      }
    }

    return false;
  }
Example #4
0
 // Produces a direct edge-to-edge path.
 private Path edgeToEdgePath(EdgeLink srcLink, EdgeLink dstLink, Path path) {
   List<Link> links = Lists.newArrayListWithCapacity(2);
   // Add source and destination edge links only if they are real and
   // add the infrastructure path only if it is not null.
   if (srcLink != NOT_HOST) {
     links.add(srcLink);
   }
   if (path != null) {
     links.addAll(path.links());
   }
   if (dstLink != NOT_HOST) {
     links.add(dstLink);
   }
   return new DefaultPath(PID, links, 2);
 }
    @Override
    public void process(PacketContext context) {
      // Stop processing if the packet has been handled, since we
      // can't do any more to it.
      if (context.isHandled()) {
        return;
      }

      InboundPacket pkt = context.inPacket();
      Ethernet ethPkt = pkt.parsed();

      if (ethPkt == null) {
        return;
      }

      // Bail if this is deemed to be a control packet.
      if (isControlPacket(ethPkt)) {
        return;
      }

      // Skip IPv6 multicast packet when IPv6 forward is disabled.
      if (!ipv6Forwarding && isIpv6Multicast(ethPkt)) {
        return;
      }

      HostId id = HostId.hostId(ethPkt.getDestinationMAC());

      // Do not process link-local addresses in any way.
      if (id.mac().isLinkLocal()) {
        return;
      }

      // Do we know who this is for? If not, flood and bail.
      Host dst = hostService.getHost(id);
      if (dst == null) {
        flood(context);
        return;
      }

      // Are we on an edge switch that our destination is on? If so,
      // simply forward out to the destination and bail.
      if (pkt.receivedFrom().deviceId().equals(dst.location().deviceId())) {
        if (!context.inPacket().receivedFrom().port().equals(dst.location().port())) {
          installRule(context, dst.location().port());
        }
        return;
      }

      // Otherwise, get a set of paths that lead from here to the
      // destination edge switch.
      Set<Path> paths =
          topologyService.getPaths(
              topologyService.currentTopology(),
              pkt.receivedFrom().deviceId(),
              dst.location().deviceId());
      if (paths.isEmpty()) {
        // If there are no paths, flood and bail.
        flood(context);
        return;
      }

      // Otherwise, pick a path that does not lead back to where we
      // came from; if no such path, flood and bail.
      Path path = pickForwardPath(paths, pkt.receivedFrom().port());
      if (path == null) {
        log.warn(
            "Doh... don't know where to go... {} -> {} received on {}",
            ethPkt.getSourceMAC(),
            ethPkt.getDestinationMAC(),
            pkt.receivedFrom());
        flood(context);
        return;
      }

      // Otherwise forward and be done with it.
      installRule(context, path.src().port());
    }