예제 #1
0
    @Override
    void processOFHello(OFHello m) throws IOException {
      OFVersion theirVersion = m.getVersion();
      OFVersion commonVersion = null;
      /* First, check if there's a version bitmap supplied. WE WILL ALWAYS HAVE a controller-provided version bitmap. */
      if (theirVersion.compareTo(OFVersion.OF_13) >= 0 && !m.getElements().isEmpty()) {
        List<U32> bitmaps = new ArrayList<U32>();
        List<OFHelloElem> elements = m.getElements();
        /* Grab all bitmaps supplied */
        for (OFHelloElem e : elements) {
          if (e instanceof OFHelloElemVersionbitmap) {
            bitmaps.addAll(((OFHelloElemVersionbitmap) e).getBitmaps());
          } else {
            log.warn("Unhandled OFHelloElem {}", e);
          }
        }
        /* Lookup highest, common supported OpenFlow version */
        commonVersion = computeOFVersionFromBitmap(bitmaps);
        if (commonVersion == null) {
          log.error(
              "Could not negotiate common OpenFlow version for {} with greatest version bitmap algorithm.",
              channel.remoteAddress());
          channel.disconnect();
          return;
        } else {
          log.info(
              "Negotiated OpenFlow version of {} for {} with greatest version bitmap algorithm.",
              commonVersion.toString(),
              channel.remoteAddress());
          factory = OFFactories.getFactory(commonVersion);
          OFMessageDecoder decoder = pipeline.get(OFMessageDecoder.class);
          decoder.setVersion(commonVersion);
        }
      }
      /* If there's not a bitmap present, choose the lower of the two supported versions. */
      else if (theirVersion.compareTo(factory.getVersion()) < 0) {
        log.info(
            "Negotiated down to switch OpenFlow version of {} for {} using lesser hello header algorithm.",
            theirVersion.toString(),
            channel.remoteAddress());
        factory = OFFactories.getFactory(theirVersion);
        OFMessageDecoder decoder = pipeline.get(OFMessageDecoder.class);
        decoder.setVersion(theirVersion);
      } /* else The controller's version is < or = the switch's, so keep original controller factory. */ else if (theirVersion
          .equals(factory.getVersion())) {
        log.info(
            "Negotiated equal OpenFlow version of {} for {} using lesser hello header algorithm.",
            factory.getVersion().toString(),
            channel.remoteAddress());
      } else {
        log.info(
            "Negotiated down to controller OpenFlow version of {} for {} using lesser hello header algorithm.",
            factory.getVersion().toString(),
            channel.remoteAddress());
      }

      setState(new WaitFeaturesReplyState());
    }