/** * Rewrite match object to use LINC OF optical extensions. * * @param match original match * @return rewritten match */ private Match rewriteMatch(Match match) { Match.Builder mBuilder = factory().buildMatch(); for (MatchField mf : match.getMatchFields()) { if (mf == MatchField.EXP_OCH_SIG_ID) { mBuilder.setExact(MatchField.OCH_SIGID, (CircuitSignalID) match.get(mf)); continue; } if (mf == MatchField.EXP_OCH_SIGTYPE) { mBuilder.setExact(MatchField.OCH_SIGTYPE, (U8) match.get(mf)); continue; } mBuilder.setExact(mf, match.get(mf)); } return mBuilder.build(); }
@Override public OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector) { ExtensionSelectorType type = extensionSelector.type(); if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI.type())) { NiciraMatchNshSpi niciraNshSpi = (NiciraMatchNshSpi) extensionSelector; return factory.oxms().nsp(U32.of(niciraNshSpi.nshSpi().servicePathId())); } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI.type())) { NiciraMatchNshSi niciraNshSi = (NiciraMatchNshSi) extensionSelector; return factory.oxms().nsi(U8.of(niciraNshSi.nshSi().serviceIndex())); } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE.type())) { NiciraMatchEncapEthType niciraEncapEthType = (NiciraMatchEncapEthType) extensionSelector; return factory.oxms().encapEthType(U16.of(niciraEncapEthType.encapEthType())); } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH1.type())) { // TODO } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH2.type())) { // TODO } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH3.type())) { // TODO } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH4.type())) { // TODO } return null; }
/** * Convert a string of bytes to a ':' separated hex string * * @param bytes * @return "0f:ca:fe:de:ad:be:ef" */ public static String toHexString(final byte[] bytes) { int i; String ret = ""; String tmp; for (i = 0; i < bytes.length; i++) { if (i > 0) ret += ":"; tmp = Integer.toHexString(U8.f(bytes[i])); if (tmp.length() == 1) ret += "0"; ret += tmp; } return ret; }
@Override public IPacket deserialize(byte[] data, int offset, int length) throws PacketParsingException { ByteBuffer bb = ByteBuffer.wrap(data, offset, length); short sscratch; this.version = bb.get(); this.headerLength = (byte) (this.version & 0xf); this.version = (byte) ((this.version >> 4) & 0xf); if (this.version != 4) { throw new PacketParsingException( "Invalid version for IPv4 packet: " + this.version); } this.diffServ = bb.get(); this.totalLength = bb.getShort(); this.identification = bb.getShort(); sscratch = bb.getShort(); this.flags = (byte) ((sscratch >> IPV4_FLAGS_SHIFT) & IPV4_FLAGS_MASK); this.fragmentOffset = (short) (sscratch & IPV4_OFFSET_MASK); this.ttl = bb.get(); this.protocol = IpProtocol.of(U8.f(bb.get())); this.checksum = bb.getShort(); this.sourceAddress = IPv4Address.of(bb.getInt()); this.destinationAddress = IPv4Address.of(bb.getInt()); if (this.headerLength > 5) { int optionsLength = (this.headerLength - 5) * 4; this.options = new byte[optionsLength]; bb.get(this.options); } IPacket payload; isFragment = ((this.flags & IPV4_FLAGS_DONTFRAG) == 0) && ((this.flags & IPV4_FLAGS_MOREFRAG) != 0 || this.fragmentOffset != 0); if (!isFragment && IPv4.protocolClassMap.containsKey(this.protocol)) { Class<? extends IPacket> clazz = IPv4.protocolClassMap.get(this.protocol); try { payload = clazz.newInstance(); } catch (Exception e) { throw new RuntimeException("Error parsing payload for IPv4 packet", e); } } else { if (log.isTraceEnabled() && isFragment) { log.trace("IPv4 fragment detected {}->{}, forward using IP header only", this.sourceAddress.toString(), this.destinationAddress.toString()); } payload = new Data(); } int payloadLength = this.totalLength - this.headerLength * 4; int remLength = bb.limit()-bb.position(); if (remLength < payloadLength) payloadLength = bb.limit()-bb.position(); this.payload = payload.deserialize(data, bb.position(), payloadLength); this.payload.setParent(this); if (this.totalLength > length) this.isTruncated = true; else this.isTruncated = false; return this; }
@Override public OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector) { ExtensionSelectorType type = extensionSelector.type(); if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI.type())) { NiciraMatchNshSpi niciraNshSpi = (NiciraMatchNshSpi) extensionSelector; return factory.oxms().nsp(U32.of(niciraNshSpi.nshSpi().servicePathId())); } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI.type())) { NiciraMatchNshSi niciraNshSi = (NiciraMatchNshSi) extensionSelector; return factory.oxms().nsi(U8.of(niciraNshSi.nshSi().serviceIndex())); } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE.type())) { NiciraMatchEncapEthType niciraEncapEthType = (NiciraMatchEncapEthType) extensionSelector; return factory.oxms().encapEthType(U16.of(niciraEncapEthType.encapEthType())); } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH1.type())) { // TODO } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH2.type())) { // TODO } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH3.type())) { // TODO } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH4.type())) { // TODO } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_STATE.type())) { NiciraMatchCtState niciraMatchCtState = (NiciraMatchCtState) extensionSelector; return factory.oxms().conntrackStateMasked(U32.of(niciraMatchCtState.ctState()), U32.of(niciraMatchCtState.ctStateMask())); } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_ZONE.type())) { NiciraMatchCtZone niciraMatchCtZone = (NiciraMatchCtZone) extensionSelector; return factory.oxms().conntrackZone(U16.of(niciraMatchCtZone.ctZone())); } if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_MARK.type())) { NiciraMatchCtMark niciraMatchCtMark = (NiciraMatchCtMark) extensionSelector; return factory.oxms().conntrackMark(U32.of(niciraMatchCtMark.ctMark())); } return null; }
@Override public OFAction mapInstruction(OFFactory factory, ExtensionTreatment extensionTreatment) { ExtensionTreatmentType type = extensionTreatment.type(); if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) { short mplsType = ((Ofdpa3SetMplsType) extensionTreatment).mplsType(); return factory.actions().setField(factory.oxms().ofdpaMplsType( U16.ofRaw(mplsType))); } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) { // OFDPA requires isPresent bit set to 1 for OVID. VlanId vlanId = ((Ofdpa3SetOvid) extensionTreatment).vlanId(); short mask = (short) 0x1000; short oVid = (short) (mask | vlanId.toShort()); return factory.actions().setField(factory.oxms().ofdpaOvid( U16.ofRaw(oVid))); } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) { Integer mplsL2Port = ((Ofdpa3SetMplsL2Port) extensionTreatment).mplsL2Port(); /* * 0x0000XXXX UNI Interface. * 0x0002XXXX NNI Interface */ if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) || (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) { return factory.actions().setField( factory.oxms().ofdpaMplsL2Port(U32.ofRaw(mplsL2Port)) ); } throw new UnsupportedOperationException( "Unexpected ExtensionTreatment: " + extensionTreatment.toString()); } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.type())) { Integer qosIndex = ((Ofdpa3SetQosIndex) extensionTreatment).qosIndex(); /* * Qos index is a single byte [0...255] */ if (qosIndex >= 0 && qosIndex <= 255) { return factory.actions().setField( factory.oxms().ofdpaQosIndex(U8.ofRaw((byte) (qosIndex & 0xFF))) ); } throw new UnsupportedOperationException( "Unexpected ExtensionTreatment: " + extensionTreatment.toString()); } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.type())) { return factory.actions().ofdpaPushL2Header(); } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.type())) { return factory.actions().ofdpaPushCw(); } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.type())) { return factory.actions().ofdpaPopL2Header(); } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.type())) { return factory.actions().ofdpaPopCw(); } throw new UnsupportedOperationException( "Unexpected ExtensionTreatment: " + extensionTreatment.toString()); }