private void sendPortStatusUpdate(OFPhysicalPort phyPort, boolean added) { FVPortStatus portStatus = new FVPortStatus(); portStatus.setDesc(phyPort); portStatus.setReason( added ? (byte) OFPortReason.OFPPR_ADD.ordinal() : (byte) OFPortReason.OFPPR_DELETE.ordinal()); FVLog.log( LogLevel.INFO, this, (added ? "added " : "removed ") + "port " + phyPort.getPortNumber()); sendMsg(portStatus, this); }
private void handleIOEvent(FVIOEvent e) { if (!this.isConnected) { try { if (!this.sock.finishConnect()) return; // not done yet } catch (IOException e1) { FVLog.log( LogLevel.DEBUG, this, "retrying connection in ", this.reconnectSeconds, " seconds; got: ", e1); this.reconnectLater(); return; } FVLog.log(LogLevel.DEBUG, this, "connected"); this.isConnected = true; this.connectCount++; HashMap<String, Object> info = this.getStatusInfo(); TopologyController tc = TopologyController.getRunningInstance(); if (tc != null) tc.sliceConnectionJustChanged(info, TopologyCallback.EventType.SLICE_CONNECTED); this.reconnectSeconds = 0; try { msgStream = new FVMessageAsyncStream(this.sock, new FVMessageFactory(), this, this.stats); } catch (IOException e1) { FVLog.log( LogLevel.WARN, this, "Trying again later; while creating OFMessageAsyncStream, got: ", e1); this.reconnectLater(); return; } sendMsg(new OFHello(), this); // send initial handshake } try { if (msgStream.needsFlush()) // flush any pending messages msgStream.flush(); List<OFMessage> msgs = this.msgStream.read(); // .read(FVSlicer.MessagesPerRead); // read any new // messages if (msgs == null) throw new IOException("got null from read()"); for (OFMessage msg : msgs) { FVLog.log(LogLevel.DEBUG, this, "recv from controller: ", msg); this.stats.increment(FVStatsType.SEND, this, msg); if ((msg instanceof SanityCheckable) && (!((SanityCheckable) msg).isSane())) { FVLog.log(LogLevel.CRIT, this, "msg failed sanity check; dropping: " + msg); continue; } if (msg instanceof Slicable) { // mark this channel as still alive this.keepAlive.registerPong(); if (msg.getType() != OFType.HELLO && !fvClassifier.isRateLimited(this.getSliceName())) { FVLog.log( LogLevel.WARN, this, "dropping msg because slice", this.getSliceName(), " is rate limited: ", msg); this.sendMsg(FVMessageUtil.makeErrorMsg(OFBadRequestCode.OFPBRC_EPERM, msg), this); continue; } ((Slicable) msg).sliceFromController(fvClassifier, this); } else FVLog.log(LogLevel.CRIT, this, "dropping msg that doesn't implement classify: ", msg); } } catch (IOException e1) { FVLog.log(LogLevel.WARN, this, "got i/o error; tearing down and reconnecting: ", e1); reconnect(); } catch (Exception e2) { e2.printStackTrace(); FVLog.log(LogLevel.ALERT, this, "got unknown error; tearing down and reconnecting: ", e2); reconnect(); } // no need to setup for next select; done in eventloop }
private void lookupByFlowSpace(FVClassifier fvClassifier) { SliceAction sliceAction; int perms; // grab single matching rule: only one because it's a point in flowspace FlowEntry flowEntry = fvClassifier .getSwitchFlowMap() .matches( fvClassifier.getSwitchInfo().getDatapathId(), this.getInPort(), this.getPacketData()); if (flowEntry == null) { FVLog.log( LogLevel.DEBUG, fvClassifier, "dropping unclassifiable msg: " + this.toVerboseString()); return; } boolean foundHome = false; // foreach slice in that rule for (OFAction ofAction : flowEntry.getActionsList()) { sliceAction = (SliceAction) ofAction; perms = sliceAction.getSlicePerms(); if ((perms & (SliceAction.READ | SliceAction.WRITE)) != 0) { // lookup slice and send msg to them // TODO record buffer id for later validation FVSlicer fvSlicer = fvClassifier.getSlicerByName(sliceAction.getSliceName()); if (fvSlicer == null) { FVLog.log( LogLevel.WARN, fvClassifier, "tried to send msg to non-existant slice: " + sliceAction.getSliceName() + " corrupted flowspace?:: " + this.toVerboseString()); continue; } if (fvSlicer.isConnected()) { if ((perms & SliceAction.WRITE) != 0) fvSlicer.setBufferIDAllowed(this.getBufferId()); fvSlicer.sendMsg(this, fvClassifier); /** * TODO : come back and decide if we should uncomment this i.e., should a rule get * squashed if it's only recipient is read only * * <p>if yes, then tests-readonly.py needs to be changed */ // if ((perms & SliceAction.WRITE) != 0) foundHome = true; } else { sendDropRule(fvClassifier, flowEntry, fvSlicer.getSliceName(), (short) 0, (short) 1); } foundHome = true; } /* * ash: not sure if this is the intended behavior, but I am guessing * that if this packet hasn't gotten handled anywhere we should at least * default to adding a drop rule for unless we want to be flooded. */ if (!foundHome) sendDropRule(fvClassifier, flowEntry, "exact", (short) 0, (short) 1); } }