Search in sources :

Example 1 with UDP

use of org.opendaylight.genius.mdsalutil.packet.UDP in project netvirt by opendaylight.

the class NaptPacketInHandler method onPacketReceived.

@Override
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public void onPacketReceived(PacketReceived packetReceived) {
    String internalIPAddress = "";
    int portNumber = 0;
    long routerId = 0L;
    NAPTEntryEvent.Operation operation = NAPTEntryEvent.Operation.ADD;
    NAPTEntryEvent.Protocol protocol;
    Short tableId = packetReceived.getTableId().getValue();
    LOG.trace("onPacketReceived : packet: {}, tableId {}", packetReceived, tableId);
    if (tableId == NwConstants.OUTBOUND_NAPT_TABLE) {
        LOG.debug("onPacketReceived : NAPTPacketInHandler Packet for Outbound NAPT Table");
        byte[] inPayload = packetReceived.getPayload();
        Ethernet ethPkt = new Ethernet();
        if (inPayload != null) {
            try {
                ethPkt.deserialize(inPayload, 0, inPayload.length * NetUtils.NUM_BITS_IN_A_BYTE);
            } catch (Exception e) {
                LOG.warn("onPacketReceived: Failed to decode Packet", e);
                return;
            }
            if (ethPkt.getPayload() instanceof IPv4) {
                IPv4 ipPkt = (IPv4) ethPkt.getPayload();
                byte[] ipSrc = Ints.toByteArray(ipPkt.getSourceAddress());
                internalIPAddress = NWUtil.toStringIpAddress(ipSrc);
                LOG.trace("onPacketReceived : Retrieved internalIPAddress {}", internalIPAddress);
                if (ipPkt.getPayload() instanceof TCP) {
                    TCP tcpPkt = (TCP) ipPkt.getPayload();
                    portNumber = tcpPkt.getSourcePort();
                    if (portNumber < 0) {
                        portNumber = 32767 + portNumber + 32767 + 2;
                        LOG.trace("onPacketReceived : Retrieved and extracted TCP portNumber {}", portNumber);
                    }
                    protocol = NAPTEntryEvent.Protocol.TCP;
                    LOG.trace("onPacketReceived : Retrieved TCP portNumber {}", portNumber);
                } else if (ipPkt.getPayload() instanceof UDP) {
                    UDP udpPkt = (UDP) ipPkt.getPayload();
                    portNumber = udpPkt.getSourcePort();
                    if (portNumber < 0) {
                        portNumber = 32767 + portNumber + 32767 + 2;
                        LOG.trace("onPacketReceived : Retrieved and extracted UDP portNumber {}", portNumber);
                    }
                    protocol = NAPTEntryEvent.Protocol.UDP;
                    LOG.trace("onPacketReceived : Retrieved UDP portNumber {}", portNumber);
                } else {
                    LOG.error("onPacketReceived : Incoming Packet is neither TCP or UDP packet");
                    return;
                }
            } else {
                LOG.error("onPacketReceived : Incoming Packet is not IPv4 packet");
                return;
            }
            if (internalIPAddress != null) {
                BigInteger metadata = packetReceived.getMatch().getMetadata().getMetadata();
                routerId = MetaDataUtil.getNatRouterIdFromMetadata(metadata);
                if (routerId <= 0) {
                    LOG.error("onPacketReceived : Router ID is invalid");
                    return;
                }
                String sourceIPPortKey = routerId + NatConstants.COLON_SEPARATOR + internalIPAddress + NatConstants.COLON_SEPARATOR + portNumber;
                NatPacketProcessingState state = incomingPacketMap.get(sourceIPPortKey);
                if (state == null) {
                    state = new NatPacketProcessingState(System.currentTimeMillis(), -1);
                    incomingPacketMap.put(sourceIPPortKey, state);
                    LOG.trace("onPacketReceived : Processing new SNAT({}) Packet", sourceIPPortKey);
                    // send to Event Queue
                    NAPTEntryEvent naptEntryEvent = new NAPTEntryEvent(internalIPAddress, portNumber, routerId, operation, protocol, packetReceived, false, state);
                    LOG.info("onPacketReceived : First Packet IN Queue Size : {}", ((ThreadPoolExecutor) firstPacketExecutorService).getQueue().size());
                    firstPacketExecutorService.execute(() -> naptEventHandler.handleEvent(naptEntryEvent));
                } else {
                    LOG.trace("onPacketReceived : SNAT({}) Packet already processed.", sourceIPPortKey);
                    NAPTEntryEvent naptEntryEvent = new NAPTEntryEvent(internalIPAddress, portNumber, routerId, operation, protocol, packetReceived, true, state);
                    LOG.debug("onPacketReceived : Retry Packet IN Queue Size : {}", ((ThreadPoolExecutor) retryPacketExecutorService).getQueue().size());
                    long firstPacketInTime = state.getFirstPacketInTime();
                    retryPacketExecutorService.execute(() -> {
                        if (System.currentTimeMillis() - firstPacketInTime > 4000) {
                            LOG.error("onPacketReceived : Flow not installed even after 4sec." + "Dropping SNAT ({}) Packet", sourceIPPortKey);
                            removeIncomingPacketMap(sourceIPPortKey);
                            return;
                        }
                        naptEventHandler.handleEvent(naptEntryEvent);
                    });
                }
            } else {
                LOG.error("onPacketReceived : Retrived internalIPAddress is NULL");
            }
        }
    } else {
        LOG.trace("onPacketReceived : Packet is not from the Outbound NAPT table");
    }
}
Also used : TCP(org.opendaylight.genius.mdsalutil.packet.TCP) UDP(org.opendaylight.genius.mdsalutil.packet.UDP) IPv4(org.opendaylight.genius.mdsalutil.packet.IPv4) Ethernet(org.opendaylight.genius.mdsalutil.packet.Ethernet) BigInteger(java.math.BigInteger) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor)

Example 2 with UDP

use of org.opendaylight.genius.mdsalutil.packet.UDP in project netvirt by opendaylight.

the class DhcpPktHandler method getDhcpPktIn.

private DHCP getDhcpPktIn(Ethernet actualEthernetPacket) {
    Ethernet ethPkt = actualEthernetPacket;
    if (ethPkt.getEtherType() == (short) NwConstants.ETHTYPE_802_1Q) {
        ethPkt = (Ethernet) ethPkt.getPayload();
    }
    // Currently only IPv4 is supported
    if (ethPkt.getPayload() instanceof IPv4) {
        IPv4 ipPkt = (IPv4) ethPkt.getPayload();
        if (ipPkt.getPayload() instanceof UDP) {
            UDP udpPkt = (UDP) ipPkt.getPayload();
            if (udpPkt.getSourcePort() == DhcpMConstants.DHCP_CLIENT_PORT && udpPkt.getDestinationPort() == DhcpMConstants.DHCP_SERVER_PORT) {
                LOG.trace("Matched DHCP_CLIENT_PORT and DHCP_SERVER_PORT");
                byte[] rawDhcpPayload = udpPkt.getRawPayload();
                DHCP reply = new DHCP();
                try {
                    reply.deserialize(rawDhcpPayload, 0, rawDhcpPayload.length);
                } catch (PacketException e) {
                    LOG.warn("Failed to deserialize DHCP pkt");
                    LOG.trace("Reason for failure", e);
                    return null;
                }
                return reply;
            }
        }
    }
    return null;
}
Also used : UDP(org.opendaylight.genius.mdsalutil.packet.UDP) Ethernet(org.opendaylight.genius.mdsalutil.packet.Ethernet) IPv4(org.opendaylight.genius.mdsalutil.packet.IPv4) DHCP(org.opendaylight.netvirt.dhcpservice.api.DHCP) PacketException(org.opendaylight.openflowplugin.libraries.liblldp.PacketException)

Example 3 with UDP

use of org.opendaylight.genius.mdsalutil.packet.UDP in project netvirt by opendaylight.

the class DhcpPktHandler method getDhcpPacketOut.

// "Consider returning a zero length array rather than null" - the eventual user of the returned byte[] likely
// expects null and it's unclear what the behavior would be if empty array was returned.
@SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
protected byte[] getDhcpPacketOut(DHCP reply, Ethernet etherPkt, String phyAddrees) {
    if (reply == null) {
        /*
             * DECLINE or RELEASE don't result in reply packet
             */
        return null;
    }
    LOG.trace("Sending DHCP Pkt {}", reply);
    InetAddress serverIp = reply.getOptionInetAddr(DHCPConstants.OPT_SERVER_IDENTIFIER);
    // create UDP pkt
    UDP udpPkt = new UDP();
    byte[] rawPkt;
    try {
        rawPkt = reply.serialize();
    } catch (PacketException e) {
        LOG.warn("Failed to serialize packet", e);
        return null;
    }
    udpPkt.setRawPayload(rawPkt);
    udpPkt.setDestinationPort(DhcpMConstants.DHCP_CLIENT_PORT);
    udpPkt.setSourcePort(DhcpMConstants.DHCP_SERVER_PORT);
    udpPkt.setLength((short) (rawPkt.length + 8));
    // Create IP Pkt
    try {
        rawPkt = udpPkt.serialize();
    } catch (PacketException e) {
        LOG.warn("Failed to serialize packet", e);
        return null;
    }
    short checkSum = 0;
    boolean computeUdpChecksum = true;
    if (computeUdpChecksum) {
        checkSum = computeChecksum(rawPkt, serverIp.getAddress(), NetUtils.intToByteArray4(DhcpMConstants.BCAST_IP));
    }
    udpPkt.setChecksum(checkSum);
    IPv4 ip4Reply = new IPv4();
    ip4Reply.setPayload(udpPkt);
    ip4Reply.setProtocol(IPProtocols.UDP.byteValue());
    ip4Reply.setSourceAddress(serverIp);
    ip4Reply.setDestinationAddress(DhcpMConstants.BCAST_IP);
    ip4Reply.setTotalLength((short) (rawPkt.length + 20));
    ip4Reply.setTtl((byte) 32);
    // create Ethernet Frame
    Ethernet ether = new Ethernet();
    if (etherPkt.getEtherType() == (short) NwConstants.ETHTYPE_802_1Q) {
        IEEE8021Q vlanPacket = (IEEE8021Q) etherPkt.getPayload();
        IEEE8021Q vlanTagged = new IEEE8021Q();
        vlanTagged.setCFI(vlanPacket.getCfi());
        vlanTagged.setPriority(vlanPacket.getPriority());
        vlanTagged.setVlanId(vlanPacket.getVlanId());
        vlanTagged.setPayload(ip4Reply);
        vlanTagged.setEtherType(EtherTypes.IPv4.shortValue());
        ether.setPayload(vlanTagged);
        ether.setEtherType((short) NwConstants.ETHTYPE_802_1Q);
    } else {
        ether.setEtherType(EtherTypes.IPv4.shortValue());
        ether.setPayload(ip4Reply);
    }
    ether.setSourceMACAddress(getServerMacAddress(phyAddrees));
    ether.setDestinationMACAddress(etherPkt.getSourceMACAddress());
    try {
        rawPkt = ether.serialize();
    } catch (PacketException e) {
        LOG.warn("Failed to serialize ethernet reply", e);
        return null;
    }
    return rawPkt;
}
Also used : UDP(org.opendaylight.genius.mdsalutil.packet.UDP) IEEE8021Q(org.opendaylight.genius.mdsalutil.packet.IEEE8021Q) IPv4(org.opendaylight.genius.mdsalutil.packet.IPv4) Ethernet(org.opendaylight.genius.mdsalutil.packet.Ethernet) InetAddress(java.net.InetAddress) PacketException(org.opendaylight.openflowplugin.libraries.liblldp.PacketException) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Example 4 with UDP

use of org.opendaylight.genius.mdsalutil.packet.UDP in project netvirt by opendaylight.

the class NaptEventHandler method buildNaptPacketOut.

@SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
protected byte[] buildNaptPacketOut(Ethernet etherPkt) {
    LOG.debug("removeNatFlows : About to build Napt Packet Out");
    if (etherPkt.getPayload() instanceof IPv4) {
        byte[] rawPkt;
        IPv4 ipPkt = (IPv4) etherPkt.getPayload();
        if (ipPkt.getPayload() instanceof TCP || ipPkt.getPayload() instanceof UDP) {
            try {
                rawPkt = etherPkt.serialize();
                return rawPkt;
            } catch (PacketException e2) {
                LOG.error("failed to build NAPT Packet out ", e2);
                return null;
            }
        } else {
            LOG.error("removeNatFlows : Unable to build NaptPacketOut since its neither TCP nor UDP");
            return null;
        }
    }
    LOG.error("removeNatFlows : Unable to build NaptPacketOut since its not IPv4 packet");
    return null;
}
Also used : TCP(org.opendaylight.genius.mdsalutil.packet.TCP) UDP(org.opendaylight.genius.mdsalutil.packet.UDP) IPv4(org.opendaylight.genius.mdsalutil.packet.IPv4) PacketException(org.opendaylight.openflowplugin.libraries.liblldp.PacketException) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Aggregations

IPv4 (org.opendaylight.genius.mdsalutil.packet.IPv4)4 UDP (org.opendaylight.genius.mdsalutil.packet.UDP)4 Ethernet (org.opendaylight.genius.mdsalutil.packet.Ethernet)3 PacketException (org.opendaylight.openflowplugin.libraries.liblldp.PacketException)3 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)2 TCP (org.opendaylight.genius.mdsalutil.packet.TCP)2 BigInteger (java.math.BigInteger)1 InetAddress (java.net.InetAddress)1 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)1 IEEE8021Q (org.opendaylight.genius.mdsalutil.packet.IEEE8021Q)1 DHCP (org.opendaylight.netvirt.dhcpservice.api.DHCP)1