use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.
the class PathVerificationService method generateVerificationPacket.
public OFPacketOut generateVerificationPacket(IOFSwitch srcSw, OFPort port, IOFSwitch dstSw, boolean sign) {
try {
OFPortDesc ofPortDesc = srcSw.getPort(port);
byte[] chassisId = new byte[] { 4, 0, 0, 0, 0, 0, 0 };
byte[] portId = new byte[] { 2, 0, 0 };
byte[] ttlValue = new byte[] { 0, 0x78 };
byte[] dpidTLVValue = new byte[] { 0x0, 0x26, (byte) 0xe1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
LLDPTLV dpidTLV = new LLDPTLV().setType((byte) 127).setLength((short) dpidTLVValue.length).setValue(dpidTLVValue);
byte[] dpidArray = new byte[8];
ByteBuffer dpidBB = ByteBuffer.wrap(dpidArray);
ByteBuffer portBB = ByteBuffer.wrap(portId, 1, 2);
DatapathId dpid = srcSw.getId();
dpidBB.putLong(dpid.getLong());
System.arraycopy(dpidArray, 2, chassisId, 1, 6);
// Set the optionalTLV to the full SwitchID
System.arraycopy(dpidArray, 0, dpidTLVValue, 4, 8);
byte[] zeroMac = { 0, 0, 0, 0, 0, 0 };
byte[] srcMac = ofPortDesc.getHwAddr().getBytes();
if (Arrays.equals(srcMac, zeroMac)) {
int portVal = ofPortDesc.getPortNo().getPortNumber();
// this is a common scenario
logger.debug("Port {}/{} has zero hardware address: overwrite with lower 6 bytes of dpid", dpid.toString(), portVal);
System.arraycopy(dpidArray, 2, srcMac, 0, 6);
}
portBB.putShort(port.getShortPortNumber());
VerificationPacket vp = new VerificationPacket();
vp.setChassisId(new LLDPTLV().setType((byte) 1).setLength((short) chassisId.length).setValue(chassisId));
vp.setPortId(new LLDPTLV().setType((byte) 2).setLength((short) portId.length).setValue(portId));
vp.setTtl(new LLDPTLV().setType((byte) 3).setLength((short) ttlValue.length).setValue(ttlValue));
vp.getOptionalTLVList().add(dpidTLV);
// Add the controller identifier to the TLV value.
// vp.getOptionalTLVList().add(controllerTLV);
// Add T0 based on format from Floodlight LLDP
long time = System.currentTimeMillis();
long swLatency = srcSw.getLatency().getValue();
byte[] timestampTLVValue = ByteBuffer.allocate(Long.SIZE / 8 + 4).put((byte) 0x00).put((byte) 0x26).put((byte) 0xe1).put(// 0x01 is what we'll use to differentiate DPID (0x00) from time (0x01)
(byte) 0x01).putLong(time + swLatency).array();
LLDPTLV timestampTLV = new LLDPTLV().setType((byte) 127).setLength((short) timestampTLVValue.length).setValue(timestampTLVValue);
vp.getOptionalTLVList().add(timestampTLV);
// Type
byte[] typeTLVValue = ByteBuffer.allocate(Integer.SIZE / 8 + 4).put((byte) 0x00).put((byte) 0x26).put((byte) 0xe1).put((byte) 0x02).putInt(PathType.ISL.ordinal()).array();
LLDPTLV typeTLV = new LLDPTLV().setType((byte) 127).setLength((short) typeTLVValue.length).setValue(typeTLVValue);
vp.getOptionalTLVList().add(typeTLV);
if (sign) {
String token = JWT.create().withClaim("dpid", dpid.getLong()).withClaim("ts", time + swLatency).sign(algorithm);
byte[] tokenBytes = token.getBytes(Charset.forName("UTF-8"));
byte[] tokenTLVValue = ByteBuffer.allocate(4 + tokenBytes.length).put((byte) 0x00).put((byte) 0x26).put((byte) 0xe1).put((byte) 0x03).put(tokenBytes).array();
LLDPTLV tokenTLV = new LLDPTLV().setType((byte) 127).setLength((short) tokenTLVValue.length).setValue(tokenTLVValue);
vp.getOptionalTLVList().add(tokenTLV);
}
MacAddress dstMac = MacAddress.of(VERIFICATION_BCAST_PACKET_DST);
if (dstSw != null) {
OFPortDesc sw2OfPortDesc = dstSw.getPort(port);
dstMac = sw2OfPortDesc.getHwAddr();
}
Ethernet l2 = new Ethernet().setSourceMACAddress(MacAddress.of(srcMac)).setDestinationMACAddress(dstMac).setEtherType(EthType.IPv4);
IPv4Address dstIp = IPv4Address.of(VERIFICATION_PACKET_IP_DST);
if (dstSw != null) {
dstIp = IPv4Address.of(((InetSocketAddress) dstSw.getInetAddress()).getAddress().getAddress());
}
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(VERIFICATION_PACKET_UDP_PORT));
l4.setDestinationPort(TransportPort.of(VERIFICATION_PACKET_UDP_PORT));
l2.setPayload(l3);
l3.setPayload(l4);
l4.setPayload(vp);
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 exception) {
logger.error("error generating verification packet: {}", exception);
}
return null;
}
use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.
the class RecordHandler method dumpRuleManagerMeters.
private void dumpRuleManagerMeters(SwitchId switchId, java.util.function.Consumer<MessageData> sender) {
try {
logger.debug("Get all meters for switch {}", switchId);
ISwitchManager switchManager = context.getSwitchManager();
DatapathId datapathId = DatapathId.of(switchId.toLong());
List<OFMeterConfig> meterEntries = switchManager.dumpMeters(datapathId);
IOFSwitch iofSwitch = switchManager.lookupSwitch(datapathId);
boolean inaccurate = featureDetectorService.detectSwitch(iofSwitch).contains(SwitchFeature.INACCURATE_METER);
List<MeterSpeakerData> meters = meterEntries.stream().map(entry -> org.openkilda.floodlight.converter.rulemanager.OfMeterConverter.INSTANCE.convertToMeterSpeakerData(entry, inaccurate)).collect(Collectors.toList());
MeterDumpResponse response = MeterDumpResponse.builder().switchId(switchId).meterSpeakerData(meters).build();
sender.accept(response);
} catch (UnsupportedSwitchOperationException e) {
logger.info("Meters not supported: {}", switchId);
sender.accept(new SwitchMeterUnsupported(switchId));
} catch (SwitchNotFoundException e) {
logger.info("Dumping switch meters is unsuccessful. Switch {} not found", switchId);
ErrorData errorData = anError(ErrorType.NOT_FOUND).withMessage(e.getMessage()).withDescription(switchId.toString()).buildData();
sender.accept(errorData);
} catch (SwitchOperationException e) {
logger.error("Unable to dump meters", e);
ErrorData errorData = anError(ErrorType.NOT_FOUND).withMessage(e.getMessage()).withDescription("Unable to dump meters").buildData();
sender.accept(errorData);
}
}
use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.
the class RecordHandler method processInstallServer42IslRttRule.
private Long processInstallServer42IslRttRule(SwitchId switchId, long cookie, int server42Port, int server42Vlan, MacAddress server42MacAddress) throws SwitchOperationException {
ISwitchManager switchManager = context.getSwitchManager();
DatapathId dpid = DatapathId.of(switchId.toLong());
if (cookie == SERVER_42_ISL_RTT_OUTPUT_COOKIE) {
return switchManager.installServer42IslRttOutputFlow(dpid, server42Port, server42Vlan, server42MacAddress);
} else if (new Cookie(cookie).getType() == CookieType.SERVER_42_ISL_RTT_INPUT) {
PortColourCookie portColourCookie = new PortColourCookie(cookie);
int islPort = portColourCookie.getPortNumber();
return switchManager.installServer42IslRttInputFlow(dpid, server42Port, islPort);
} else {
logger.warn("Skipping the installation of unexpected server 42 switch rule {} for switch {}", Long.toHexString(cookie), switchId);
return null;
}
}
use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.
the class RecordHandler method processInstallServer42RttRule.
private void processInstallServer42RttRule(InstallServer42Flow command) throws SwitchOperationException {
ISwitchManager switchManager = context.getSwitchManager();
DatapathId dpid = DatapathId.of(command.getSwitchId().toLong());
Cookie cookie = new Cookie(command.getCookie());
FlowSharedSegmentCookie sharedSegmentCookie = new FlowSharedSegmentCookie(command.getCookie());
if (command.getCookie() == SERVER_42_FLOW_RTT_OUTPUT_VLAN_COOKIE) {
switchManager.installServer42FlowRttOutputVlanFlow(dpid, command.getOutputPort(), command.getServer42Vlan(), command.getServer42MacAddress());
} else if (command.getCookie() == SERVER_42_FLOW_RTT_OUTPUT_VXLAN_COOKIE) {
switchManager.installServer42FlowRttOutputVxlanFlow(dpid, command.getOutputPort(), command.getServer42Vlan(), command.getServer42MacAddress());
} else if (cookie.getType() == CookieType.SERVER_42_FLOW_RTT_INPUT) {
PortColourCookie portColourCookie = new PortColourCookie(command.getCookie());
int customerPort = portColourCookie.getPortNumber();
switchManager.installServer42FlowRttInputFlow(dpid, command.getInputPort(), customerPort, command.getServer42MacAddress());
} else if (cookie.getType() == CookieType.SHARED_OF_FLOW && sharedSegmentCookie.getSegmentType() == SharedSegmentType.SERVER42_QINQ_OUTER_VLAN) {
switchManager.installServer42OuterVlanMatchSharedFlow(dpid, sharedSegmentCookie);
} else if (command.getCookie() == SERVER_42_ISL_RTT_OUTPUT_COOKIE) {
processInstallServer42IslRttRule(command.getSwitchId(), command.getCookie(), command.getOutputPort(), command.getServer42Vlan(), command.getServer42MacAddress());
} else if (cookie.getType() == CookieType.SERVER_42_ISL_RTT_INPUT) {
processInstallServer42IslRttRule(command.getSwitchId(), command.getCookie(), command.getInputPort(), command.getServer42Vlan(), command.getServer42MacAddress());
} else {
logger.warn("Skipping the installation of unexpected server 42 switch rule {} for switch {}", Long.toHexString(command.getCookie()), command.getSwitchId());
}
}
use of org.projectfloodlight.openflow.types.DatapathId in project open-kilda by telstra.
the class RecordHandler method doDeleteMeter.
private void doDeleteMeter(CommandMessage message, String replyToTopic) {
DeleteMeterRequest request = (DeleteMeterRequest) message.getData();
logger.info("Deleting meter '{}'. Switch: '{}'", request.getMeterId(), request.getSwitchId());
final IKafkaProducerService producerService = getKafkaProducer();
try {
DatapathId dpid = DatapathId.of(request.getSwitchId().toLong());
context.getSwitchManager().deleteMeter(dpid, request.getMeterId());
boolean deleted = context.getSwitchManager().dumpMeters(dpid).stream().noneMatch(config -> config.getMeterId() == request.getMeterId());
DeleteMeterResponse response = new DeleteMeterResponse(deleted);
InfoMessage infoMessage = new InfoMessage(response, System.currentTimeMillis(), message.getCorrelationId());
producerService.sendMessageAndTrack(replyToTopic, message.getCorrelationId(), infoMessage);
} catch (SwitchOperationException e) {
logger.error("Deleting meter '{}' from switch '{}' was unsuccessful: {}", request.getMeterId(), request.getSwitchId(), e.getMessage());
anError(ErrorType.DATA_INVALID).withMessage(e.getMessage()).withDescription(request.getSwitchId().toString()).withCorrelationId(message.getCorrelationId()).withTopic(replyToTopic).sendVia(producerService);
}
}
Aggregations