private void sendPacketOut(ConnectPoint outport, Ethernet payload, int sid) { IPv4 ipPacket = (IPv4) payload.getPayload(); Ip4Address destIpAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress()); if (sid == -1 || config.getSegmentId(payload.getDestinationMAC()) == sid || config.inSameSubnet(outport.deviceId(), destIpAddress)) { TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(outport.port()).build(); OutboundPacket packet = new DefaultOutboundPacket( outport.deviceId(), treatment, ByteBuffer.wrap(payload.serialize())); srManager.packetService.emit(packet); } else { log.info("Send a MPLS packet as a ICMP response"); TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(outport.port()).build(); payload.setEtherType(Ethernet.MPLS_UNICAST); MPLS mplsPkt = new MPLS(); mplsPkt.setLabel(sid); mplsPkt.setTtl(((IPv4) payload.getPayload()).getTtl()); mplsPkt.setPayload(payload.getPayload()); payload.setPayload(mplsPkt); OutboundPacket packet = new DefaultOutboundPacket( outport.deviceId(), treatment, ByteBuffer.wrap(payload.serialize())); srManager.packetService.emit(packet); } }
/** * Sends an ICMP reply message. * * <p>Note: we assume that packets sending from the edge switches to the hosts have untagged VLAN. * * @param icmpRequest the original ICMP request * @param outport the output port where the ICMP reply should be sent to */ private void sendICMPResponse(Ethernet icmpRequest, ConnectPoint outport) { // Note: We assume that packets arrive at the edge switches have // untagged VLAN. Ethernet icmpReplyEth = new Ethernet(); IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload(); IPv4 icmpReplyIpv4 = new IPv4(); int destAddress = icmpRequestIpv4.getDestinationAddress(); icmpReplyIpv4.setDestinationAddress(icmpRequestIpv4.getSourceAddress()); icmpReplyIpv4.setSourceAddress(destAddress); icmpReplyIpv4.setTtl((byte) 64); icmpReplyIpv4.setChecksum((short) 0); ICMP icmpReply = new ICMP(); icmpReply.setPayload(((ICMP) icmpRequestIpv4.getPayload()).getPayload()); icmpReply.setIcmpType(ICMP.TYPE_ECHO_REPLY); icmpReply.setIcmpCode(ICMP.SUBTYPE_ECHO_REPLY); icmpReply.setChecksum((short) 0); icmpReplyIpv4.setPayload(icmpReply); icmpReplyEth.setPayload(icmpReplyIpv4); icmpReplyEth.setEtherType(Ethernet.TYPE_IPV4); icmpReplyEth.setDestinationMACAddress(icmpRequest.getSourceMACAddress()); icmpReplyEth.setSourceMACAddress(icmpRequest.getDestinationMACAddress()); Ip4Address destIpAddress = Ip4Address.valueOf(icmpReplyIpv4.getDestinationAddress()); Ip4Address destRouterAddress = config.getRouterIpAddressForASubnetHost(destIpAddress); int sid = config.getSegmentId(destRouterAddress); if (sid < 0) { log.warn("Cannot find the Segment ID for {}", destAddress); return; } sendPacketOut(outport, icmpReplyEth, sid); }