@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()); }