Search in sources :

Example 36 with DatapathId

use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.

the class PathVerificationService method generateDiscoveryPacket.

/**
 * Return Discovery packet.
 *
 * @param srcSw source switch.
 * @param port port.
 * @param sign sign.
 * @param packetId id of the packet.
 * @return discovery packet.
 */
OFPacketOut generateDiscoveryPacket(IOFSwitch srcSw, OFPort port, boolean sign, Long packetId) {
    try {
        byte[] dpidArray = new byte[8];
        ByteBuffer dpidBb = ByteBuffer.wrap(dpidArray);
        DatapathId dpid = srcSw.getId();
        dpidBb.putLong(dpid.getLong());
        byte[] chassisId = new byte[] { 4, 0, 0, 0, 0, 0, 0 };
        System.arraycopy(dpidArray, 2, chassisId, 1, 6);
        // Set the optionalTLV to the full SwitchID
        byte[] dpidTlvValue = Arrays.concatenate(ORGANIZATIONALLY_UNIQUE_IDENTIFIER, new byte[] { REMOTE_SWITCH_OPTIONAL_TYPE, 0, 0, 0, 0, 0, 0, 0, 0 });
        System.arraycopy(dpidArray, 0, dpidTlvValue, LLDP_TLV_OPTIONAL_HEADER_SIZE_IN_BYTES, 8);
        // Set src mac to be able to detect the origin of the packet.
        // NB: previously we set port's address instead of switch (some switches declare unique address per port)
        byte[] srcMac = new byte[6];
        System.arraycopy(dpidArray, 2, srcMac, 0, 6);
        byte[] portId = new byte[] { 2, 0, 0 };
        ByteBuffer portBb = ByteBuffer.wrap(portId, 1, 2);
        portBb.putShort(port.getShortPortNumber());
        byte[] ttlValue = new byte[] { 0, 0x78 };
        DiscoveryPacket dp = DiscoveryPacket.builder().chassisId(makeIdLldptvPacket(chassisId, CHASSIS_ID_LLDPTV_PACKET_TYPE)).portId(makeIdLldptvPacket(portId, PORT_ID_LLDPTV_PACKET_TYPE)).ttl(makeIdLldptvPacket(ttlValue, TTL_LLDPTV_PACKET_TYPE)).build();
        // Add TLV for t0, this will be overwritten by the switch if it supports switch timestamps
        dp.getOptionalTlvList().add(switchTimestampTlv(SWITCH_T0_OPTIONAL_TYPE));
        // Add TLV for t1, this will be overwritten by the switch if it supports switch timestamps
        dp.getOptionalTlvList().add(switchTimestampTlv(SWITCH_T1_OPTIONAL_TYPE));
        LLDPTLV dpidTlv = makeIdLldptvPacket(dpidTlvValue, OPTIONAL_LLDPTV_PACKET_TYPE);
        dp.getOptionalTlvList().add(dpidTlv);
        // Add T0 based on format from Floodlight LLDP
        long time = System.currentTimeMillis();
        long swLatency = srcSw.getLatency().getValue();
        byte[] timestampTlvValue = ByteBuffer.allocate(Long.SIZE / 8 + LLDP_TLV_OPTIONAL_HEADER_SIZE_IN_BYTES).put(ORGANIZATIONALLY_UNIQUE_IDENTIFIER).put(// 0x01 is what we'll use to differentiate DPID 0x00 from time 0x01
        TIMESTAMP_OPTIONAL_TYPE).putLong(time + swLatency).array();
        LLDPTLV timestampTlv = makeIdLldptvPacket(timestampTlvValue, OPTIONAL_LLDPTV_PACKET_TYPE);
        dp.getOptionalTlvList().add(timestampTlv);
        // Type
        byte[] typeTlvValue = ByteBuffer.allocate(Integer.SIZE / 8 + LLDP_TLV_OPTIONAL_HEADER_SIZE_IN_BYTES).put(ORGANIZATIONALLY_UNIQUE_IDENTIFIER).put(PATH_ORDINAL_OPTIONAL_TYPE).putInt(PathType.ISL.ordinal()).array();
        LLDPTLV typeTlv = makeIdLldptvPacket(typeTlvValue, OPTIONAL_LLDPTV_PACKET_TYPE);
        dp.getOptionalTlvList().add(typeTlv);
        if (sign) {
            Builder builder = JWT.create().withClaim("dpid", dpid.getLong()).withClaim("ts", time + swLatency);
            if (packetId != null) {
                builder.withClaim("id", packetId);
            }
            String token = builder.sign(algorithm);
            byte[] tokenBytes = token.getBytes(Charset.forName("UTF-8"));
            byte[] tokenTlvValue = ByteBuffer.allocate(LLDP_TLV_OPTIONAL_HEADER_SIZE_IN_BYTES + tokenBytes.length).put(ORGANIZATIONALLY_UNIQUE_IDENTIFIER).put(TOKEN_OPTIONAL_TYPE).put(tokenBytes).array();
            LLDPTLV tokenTlv = makeIdLldptvPacket(tokenTlvValue, OPTIONAL_LLDPTV_PACKET_TYPE);
            dp.getOptionalTlvList().add(tokenTlv);
        }
        MacAddress dstMac = MacAddress.of(config.getVerificationBcastPacketDst());
        IPv4Address dstIp = IPv4Address.of(DISCOVERY_PACKET_IP_DST);
        IPv4 l3 = new IPv4().setSourceAddress(IPv4Address.of(((InetSocketAddress) srcSw.getInetAddress()).getAddress().getAddress())).setDestinationAddress(dstIp).setTtl((byte) 64).setProtocol(IpProtocol.UDP);
        UDP l4 = new UDP();
        l4.setSourcePort(TransportPort.of(DISCOVERY_PACKET_UDP_PORT));
        l4.setDestinationPort(TransportPort.of(DISCOVERY_PACKET_UDP_PORT));
        Ethernet l2 = new Ethernet().setSourceMACAddress(MacAddress.of(srcMac)).setDestinationMACAddress(dstMac).setEtherType(EthType.IPv4);
        l2.setPayload(l3);
        l3.setPayload(l4);
        l4.setPayload(dp);
        byte[] data = l2.serialize();
        OFPacketOut.Builder pob = srcSw.getOFFactory().buildPacketOut().setBufferId(OFBufferId.NO_BUFFER).setActions(getDiscoveryActions(srcSw, port)).setData(data);
        OFMessageUtils.setInPort(pob, OFPort.CONTROLLER);
        return pob.build();
    } catch (Exception e) {
        logger.error(String.format("error generating discovery packet: %s", e.getMessage()), e);
    }
    return null;
}
Also used : UDP(net.floodlightcontroller.packet.UDP) InetSocketAddress(java.net.InetSocketAddress) Builder(com.auth0.jwt.JWTCreator.Builder) IPv4(net.floodlightcontroller.packet.IPv4) DatapathId(org.projectfloodlight.openflow.types.DatapathId) MacAddress(org.projectfloodlight.openflow.types.MacAddress) ByteBuffer(java.nio.ByteBuffer) IPv4Address(org.projectfloodlight.openflow.types.IPv4Address) OFPacketOut(org.projectfloodlight.openflow.protocol.OFPacketOut) UnsupportedEncodingException(java.io.UnsupportedEncodingException) JWTVerificationException(com.auth0.jwt.exceptions.JWTVerificationException) FloodlightModuleException(net.floodlightcontroller.core.module.FloodlightModuleException) OFPortDescPropEthernet(org.projectfloodlight.openflow.protocol.OFPortDescPropEthernet) Ethernet(net.floodlightcontroller.packet.Ethernet) LLDPTLV(net.floodlightcontroller.packet.LLDPTLV)

Example 37 with DatapathId

use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.

the class RecordHandler method doConfigurePort.

private void doConfigurePort(final CommandMessage message) {
    PortConfigurationRequest request = (PortConfigurationRequest) message.getData();
    logger.info("Port configuration request. Switch '{}', Port '{}'", request.getSwitchId(), request.getPortNumber());
    final IKafkaProducerService producerService = getKafkaProducer();
    final String replyToTopic = context.getKafkaNorthboundTopic();
    try {
        ISwitchManager switchManager = context.getSwitchManager();
        DatapathId dpId = DatapathId.of(request.getSwitchId().toLong());
        switchManager.configurePort(dpId, request.getPortNumber(), request.getAdminDown());
        InfoMessage infoMessage = new InfoMessage(new PortConfigurationResponse(request.getSwitchId(), request.getPortNumber()), message.getTimestamp(), message.getCorrelationId());
        producerService.sendMessageAndTrack(replyToTopic, infoMessage);
    } catch (SwitchOperationException e) {
        logger.error("Port configuration request failed. " + e.getMessage(), e);
        anError(ErrorType.DATA_INVALID).withMessage(e.getMessage()).withDescription("Port configuration request failed").withCorrelationId(message.getCorrelationId()).withTopic(replyToTopic).sendVia(producerService);
    }
}
Also used : PortConfigurationRequest(org.openkilda.messaging.command.switches.PortConfigurationRequest) SwitchOperationException(org.openkilda.floodlight.error.SwitchOperationException) UnsupportedSwitchOperationException(org.openkilda.floodlight.error.UnsupportedSwitchOperationException) ISwitchManager(org.openkilda.floodlight.switchmanager.ISwitchManager) IKafkaProducerService(org.openkilda.floodlight.service.kafka.IKafkaProducerService) InfoMessage(org.openkilda.messaging.info.InfoMessage) DatapathId(org.projectfloodlight.openflow.types.DatapathId) PortConfigurationResponse(org.openkilda.messaging.info.switches.PortConfigurationResponse)

Example 38 with DatapathId

use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.

the class RecordHandler method doModifyMeterRequest.

private void doModifyMeterRequest(CommandMessage message) {
    MeterModifyCommandRequest request = (MeterModifyCommandRequest) message.getData();
    final IKafkaProducerService producerService = getKafkaProducer();
    String replyToTopic = context.getKafkaNbWorkerTopic();
    SwitchId switchId = request.getSwitchId();
    DatapathId datapathId = DatapathId.of(switchId.toLong());
    long meterId = request.getMeterId();
    ISwitchManager switchManager = context.getSwitchManager();
    try {
        switchManager.modifyMeterForFlow(datapathId, meterId, request.getBandwidth());
        MeterEntry meterEntry = OfMeterConverter.toMeterEntry(switchManager.dumpMeterById(datapathId, meterId));
        SwitchMeterEntries response = SwitchMeterEntries.builder().switchId(switchId).meterEntries(ImmutableList.of(meterEntry)).build();
        InfoMessage infoMessage = new InfoMessage(response, message.getTimestamp(), message.getCorrelationId());
        producerService.sendMessageAndTrack(replyToTopic, message.getCorrelationId(), infoMessage);
    } catch (UnsupportedSwitchOperationException e) {
        String messageString = String.format("Not supported: %s", new SwitchId(e.getDpId().getLong()));
        logger.error(messageString, e);
        anError(ErrorType.PARAMETERS_INVALID).withMessage(e.getMessage()).withDescription(messageString).withCorrelationId(message.getCorrelationId()).withTopic(replyToTopic).sendVia(producerService);
    } catch (SwitchNotFoundException e) {
        logger.error("Update switch meters is unsuccessful. Switch {} not found", new SwitchId(e.getDpId().getLong()));
        anError(ErrorType.NOT_FOUND).withMessage(e.getMessage()).withDescription(new SwitchId(e.getDpId().getLong()).toString()).withCorrelationId(message.getCorrelationId()).withTopic(replyToTopic).sendVia(producerService);
    } catch (SwitchOperationException e) {
        String messageString = "Unable to update meter";
        logger.error(messageString, e);
        anError(ErrorType.NOT_FOUND).withMessage(e.getMessage()).withDescription(messageString).withCorrelationId(message.getCorrelationId()).withTopic(replyToTopic).sendVia(producerService);
    }
}
Also used : SwitchOperationException(org.openkilda.floodlight.error.SwitchOperationException) UnsupportedSwitchOperationException(org.openkilda.floodlight.error.UnsupportedSwitchOperationException) ISwitchManager(org.openkilda.floodlight.switchmanager.ISwitchManager) SwitchMeterEntries(org.openkilda.messaging.info.meter.SwitchMeterEntries) SwitchId(org.openkilda.model.SwitchId) DatapathId(org.projectfloodlight.openflow.types.DatapathId) SwitchNotFoundException(org.openkilda.floodlight.error.SwitchNotFoundException) MeterEntry(org.openkilda.messaging.info.meter.MeterEntry) UnsupportedSwitchOperationException(org.openkilda.floodlight.error.UnsupportedSwitchOperationException) IKafkaProducerService(org.openkilda.floodlight.service.kafka.IKafkaProducerService) InfoMessage(org.openkilda.messaging.info.InfoMessage) MeterModifyCommandRequest(org.openkilda.messaging.command.flow.MeterModifyCommandRequest)

Example 39 with DatapathId

use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.

the class RecordHandler method doModifyDefaultMeterForSwitchManager.

private void doModifyDefaultMeterForSwitchManager(CommandMessage message) {
    ModifyDefaultMeterForSwitchManagerRequest request = (ModifyDefaultMeterForSwitchManagerRequest) message.getData();
    IKafkaProducerService producerService = getKafkaProducer();
    String replyToTopic = context.getKafkaSwitchManagerTopic();
    long meterId = request.getMeterId();
    SwitchId switchId = request.getSwitchId();
    DatapathId dpid = DatapathId.of(switchId.toLong());
    try {
        context.getSwitchManager().modifyDefaultMeter(dpid, request.getMeterId());
        InfoMessage response = new InfoMessage(new ModifyMeterResponse(switchId, request.getMeterId()), System.currentTimeMillis(), message.getCorrelationId());
        producerService.sendMessageAndTrack(replyToTopic, message.getCorrelationId(), response);
    } catch (UnsupportedSwitchOperationException e) {
        logger.warn(format("Skip meter %d modification on switch %s because switch doesn't support meters", meterId, switchId), e);
    } catch (InvalidMeterIdException | OfInstallException | SwitchNotFoundException e) {
        logger.error("Failed to modify meter {} for switch: '{}'", request.getSwitchId(), meterId, e);
        ErrorType errorType;
        if (e instanceof InvalidMeterIdException) {
            errorType = ErrorType.DATA_INVALID;
        } else if (e instanceof SwitchNotFoundException) {
            errorType = ErrorType.NOT_FOUND;
        } else {
            errorType = ErrorType.INTERNAL_ERROR;
        }
        anError(errorType).withMessage(e.getMessage()).withDescription(request.getSwitchId().toString()).withCorrelationId(message.getCorrelationId()).withTopic(replyToTopic).sendVia(producerService);
    }
}
Also used : ModifyMeterResponse(org.openkilda.messaging.info.switches.ModifyMeterResponse) InvalidMeterIdException(org.openkilda.floodlight.error.InvalidMeterIdException) SwitchId(org.openkilda.model.SwitchId) DatapathId(org.projectfloodlight.openflow.types.DatapathId) SwitchNotFoundException(org.openkilda.floodlight.error.SwitchNotFoundException) UnsupportedSwitchOperationException(org.openkilda.floodlight.error.UnsupportedSwitchOperationException) ErrorType(org.openkilda.messaging.error.ErrorType) ModifyDefaultMeterForSwitchManagerRequest(org.openkilda.messaging.command.flow.ModifyDefaultMeterForSwitchManagerRequest) IKafkaProducerService(org.openkilda.floodlight.service.kafka.IKafkaProducerService) InfoMessage(org.openkilda.messaging.info.InfoMessage) OfInstallException(org.openkilda.floodlight.error.OfInstallException)

Example 40 with DatapathId

use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.

the class RecordHandler method doDeleteFlowForSwitchManager.

/**
 * Removes flow.
 *
 * @param message command message for flow deletion
 */
private void doDeleteFlowForSwitchManager(final CommandMessage message) {
    RemoveFlowForSwitchManagerRequest request = (RemoveFlowForSwitchManagerRequest) message.getData();
    IKafkaProducerService producerService = getKafkaProducer();
    String replyToTopic = context.getKafkaSwitchManagerTopic();
    DatapathId dpid = DatapathId.of(request.getSwitchId().toLong());
    try {
        processDeleteFlow(request.getFlowCommand(), dpid);
        InfoMessage response = new InfoMessage(new FlowRemoveResponse(), System.currentTimeMillis(), message.getCorrelationId());
        producerService.sendMessageAndTrack(replyToTopic, message.getCorrelationId(), response);
    } catch (SwitchOperationException e) {
        logger.error("Failed to process switch rule deletion for switch: '{}'", request.getSwitchId(), e);
        anError(ErrorType.DELETION_FAILURE).withMessage(e.getMessage()).withDescription(request.getSwitchId().toString()).withCorrelationId(message.getCorrelationId()).withTopic(replyToTopic).sendVia(producerService);
    }
}
Also used : SwitchOperationException(org.openkilda.floodlight.error.SwitchOperationException) UnsupportedSwitchOperationException(org.openkilda.floodlight.error.UnsupportedSwitchOperationException) RemoveFlowForSwitchManagerRequest(org.openkilda.messaging.command.flow.RemoveFlowForSwitchManagerRequest) IKafkaProducerService(org.openkilda.floodlight.service.kafka.IKafkaProducerService) InfoMessage(org.openkilda.messaging.info.InfoMessage) DatapathId(org.projectfloodlight.openflow.types.DatapathId) FlowRemoveResponse(org.openkilda.messaging.info.flow.FlowRemoveResponse)

Aggregations

DatapathId (org.projectfloodlight.openflow.types.DatapathId)55 InfoMessage (org.openkilda.messaging.info.InfoMessage)19 UnsupportedSwitchOperationException (org.openkilda.floodlight.error.UnsupportedSwitchOperationException)17 IOFSwitch (net.floodlightcontroller.core.IOFSwitch)16 SwitchOperationException (org.openkilda.floodlight.error.SwitchOperationException)16 ISwitchManager (org.openkilda.floodlight.switchmanager.ISwitchManager)16 OFFactory (org.projectfloodlight.openflow.protocol.OFFactory)15 IKafkaProducerService (org.openkilda.floodlight.service.kafka.IKafkaProducerService)14 SwitchId (org.openkilda.model.SwitchId)14 OFMessage (org.projectfloodlight.openflow.protocol.OFMessage)13 SwitchNotFoundException (org.openkilda.floodlight.error.SwitchNotFoundException)12 OFPortDesc (org.projectfloodlight.openflow.protocol.OFPortDesc)10 ArrayList (java.util.ArrayList)9 InetSocketAddress (java.net.InetSocketAddress)8 HashSet (java.util.HashSet)8 Map (java.util.Map)8 InvalidMeterIdException (org.openkilda.floodlight.error.InvalidMeterIdException)8 OfInstallException (org.openkilda.floodlight.error.OfInstallException)8 Objects (java.util.Objects)7 Collectors (java.util.stream.Collectors)7