package org.freertr.serv; import org.freertr.addr.addrMac; import org.freertr.ifc.ifcEther; import org.freertr.pack.packHolder; import org.freertr.pack.packOpenflow; import org.freertr.pipe.pipeSide; import org.freertr.util.counter; import org.freertr.util.debugger; import org.freertr.util.logger; import org.freertr.util.state; /** * one openflow receiver * * @author matecsaba */ class servOpenflowRx implements Runnable { /** * true if the transmitter is working */ public boolean working = true; private final pipeSide pipe; private final servOpenflow lower; public servOpenflowRx(pipeSide stream, servOpenflow parent) { pipe = stream; lower = parent; new Thread(this).start(); } public void run() { try { doWord(); } catch (Exception e) { logger.traceback(e); } pipe.setClose(); lower.notif.wakeup(); } private void doWord() { packHolder pckB = new packHolder(true, true); packOpenflow pckO = new packOpenflow(); pckO.pipe = pipe; for (;;) { if (!working) { return; } if (pckO.recvPack(pckB)) { return; } if (debugger.servOpenflowRx) { logger.debug("rx " + pckO.dump(pckB)); } switch (pckO.type) { case packOpenflow.typHello: break; case packOpenflow.typEchoReq: pckO.createEchoRep(); lower.sendPack(pckB, pckO); break; case packOpenflow.typEchoRep: break; case packOpenflow.typPortStat: servOpenflowIfc1 ntry = new servOpenflowIfc1(); ntry.id = pckB.msbGetD(8); ntry = lower.expIfc.find(ntry); if (ntry == null) { break; } if ((pckB.msbGetD(44) & 1) != 0) { ntry.lastState = state.states.down; } else { ntry.lastState = state.states.up; } ntry.upper.setState(ntry.lastState); break; case packOpenflow.typPackIn: lower.cntr.rx(pckB); ntry = new servOpenflowIfc1(); ntry.id = pckO.parsePckIn(pckB); ntry = lower.expIfc.find(ntry); if (ntry == null) { lower.cntr.drop(pckB, counter.reasons.noIface); break; } ifcEther.parseETHheader(pckB, false); ntry.upper.recvPack(pckB); break; case packOpenflow.typMultiRep: switch (pckB.msbGetW(0)) { case 4: pckB.getSkip(8); int i = pckB.msbGetD(0); if (debugger.servOpenflowRx) { logger.debug("port #" + i + " stats"); } ntry = new servOpenflowIfc1(); ntry.id = i; ntry = lower.expIfc.find(ntry); if (ntry == null) { break; } ntry.ifc.ethtyp.hwCntr.packRx = pckB.msbGetQ(8); ntry.ifc.ethtyp.hwCntr.packTx = pckB.msbGetQ(16); ntry.ifc.ethtyp.hwCntr.byteRx = pckB.msbGetQ(24); ntry.ifc.ethtyp.hwCntr.byteTx = pckB.msbGetQ(32); ntry.ifc.ethtyp.hwCntr.packDr = pckB.msbGetQ(40) + pckB.msbGetQ(48); ntry.ifc.ethtyp.hwHstry.update(ntry.ifc.ethtyp.hwCntr); if (ntry.ifc.ethtyp.hwSub == null) { break; } ntry.ifc.ethtyp.hwCntr = ntry.ifc.ethtyp.hwCntr.minus(ntry.ifc.ethtyp.hwSub); break; case 13: pckB.getSkip(8); i = pckB.msbGetD(0); addrMac mac = new addrMac(); pckB.getAddr(mac, 8); if (debugger.servOpenflowRx) { logger.debug("port #" + i + " mac=" + mac); } break; } break; case packOpenflow.typFeatRep: if (debugger.servOpenflowRx) { logger.debug("datapath=" + pckB.msbGetQ(0) + " buffers=" + pckB.msbGetD(8) + " tables=" + pckB.getByte(12)); } break; default: logger.info("got invalid message type=" + pckO.type); break; } } } }