Search in sources :

Example 1 with DHCP

use of org.opendaylight.netvirt.dhcpservice.api.DHCP 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 2 with DHCP

use of org.opendaylight.netvirt.dhcpservice.api.DHCP in project netvirt by opendaylight.

the class DhcpPktHandler method handleDhcpPacket.

private DHCP handleDhcpPacket(DHCP dhcpPkt, String interfaceName, String macAddress, Port interfacePort, Subnet subnet, String serverIp) {
    LOG.trace("DHCP pkt rcvd {}", dhcpPkt);
    byte msgType = dhcpPkt.getMsgType();
    DhcpInfo dhcpInfo = null;
    if (interfacePort != null) {
        dhcpInfo = handleDhcpNeutronPacket(msgType, interfacePort, subnet, serverIp);
    } else if (config.isDhcpDynamicAllocationPoolEnabled()) {
        dhcpInfo = handleDhcpAllocationPoolPacket(msgType, interfaceName, macAddress);
    }
    DHCP reply = null;
    if (dhcpInfo != null) {
        if (msgType == DHCPConstants.MSG_DISCOVER) {
            reply = getReplyToDiscover(dhcpPkt, dhcpInfo);
        } else if (msgType == DHCPConstants.MSG_REQUEST) {
            reply = getReplyToRequest(dhcpPkt, dhcpInfo);
        }
    }
    return reply;
}
Also used : DHCP(org.opendaylight.netvirt.dhcpservice.api.DHCP)

Example 3 with DHCP

use of org.opendaylight.netvirt.dhcpservice.api.DHCP in project netvirt by opendaylight.

the class DhcpPktHandler method getReplyToRequest.

DHCP getReplyToRequest(DHCP dhcpPkt, DhcpInfo dhcpInfo) {
    boolean sendAck = false;
    byte[] requestedIp = null;
    DHCP reply = new DHCP();
    reply.setOp(DHCPConstants.BOOTREPLY);
    reply.setHtype(dhcpPkt.getHtype());
    reply.setHlen(dhcpPkt.getHlen());
    reply.setHops((byte) 0);
    reply.setXid(dhcpPkt.getXid());
    reply.setSecs((short) 0);
    reply.setFlags(dhcpPkt.getFlags());
    reply.setGiaddr(dhcpPkt.getGiaddr());
    reply.setChaddr(dhcpPkt.getChaddr());
    byte[] allocatedIp;
    try {
        allocatedIp = DHCPUtils.strAddrToByteArray(dhcpInfo.getClientIp());
    } catch (UnknownHostException e) {
        LOG.debug("strAddrToByteArray", e);
        allocatedIp = null;
    }
    if (Arrays.equals(allocatedIp, dhcpPkt.getCiaddr())) {
        // This means a renew request
        sendAck = true;
    } else {
        requestedIp = dhcpPkt.getOptionBytes(DHCPConstants.OPT_REQUESTED_ADDRESS);
        sendAck = Arrays.equals(allocatedIp, requestedIp);
    }
    if (sendAck) {
        reply.setCiaddr(dhcpPkt.getCiaddr());
        reply.setYiaddr(dhcpInfo.getClientIp());
        reply.setSiaddr(dhcpInfo.getServerIp());
        reply.setMsgType(DHCPConstants.MSG_ACK);
        if (dhcpPkt.containsOption(DHCPConstants.OPT_PARAMETER_REQUEST_LIST)) {
            setParameterListOptions(dhcpPkt, reply, dhcpInfo);
        }
    } else {
        reply.setMsgType(DHCPConstants.MSG_NAK);
    }
    setCommonOptions(reply, dhcpInfo);
    return reply;
}
Also used : UnknownHostException(java.net.UnknownHostException) DHCP(org.opendaylight.netvirt.dhcpservice.api.DHCP)

Example 4 with DHCP

use of org.opendaylight.netvirt.dhcpservice.api.DHCP in project netvirt by opendaylight.

the class DhcpPktHandler method onPacketReceived.

// TODO: Handle this in a separate thread
@Override
public void onPacketReceived(PacketReceived packet) {
    if (!config.isControllerDhcpEnabled()) {
        return;
    }
    Class<? extends PacketInReason> pktInReason = packet.getPacketInReason();
    short tableId = packet.getTableId().getValue();
    if ((tableId == NwConstants.DHCP_TABLE || tableId == NwConstants.DHCP_TABLE_EXTERNAL_TUNNEL) && isPktInReasonSendtoCtrl(pktInReason)) {
        byte[] inPayload = packet.getPayload();
        Ethernet ethPkt = new Ethernet();
        try {
            ethPkt.deserialize(inPayload, 0, inPayload.length * NetUtils.NUM_BITS_IN_A_BYTE);
        } catch (PacketException e) {
            LOG.warn("Failed to decode DHCP Packet.", e);
            LOG.trace("Received packet {}", packet);
            return;
        }
        DHCP pktIn;
        pktIn = getDhcpPktIn(ethPkt);
        if (pktIn != null) {
            LOG.trace("DHCPPkt received: {}", pktIn);
            LOG.trace("Received Packet: {}", packet);
            BigInteger metadata = packet.getMatch().getMetadata().getMetadata();
            long portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
            String macAddress = DHCPUtils.byteArrayToString(ethPkt.getSourceMACAddress());
            BigInteger tunnelId = packet.getMatch().getTunnel() == null ? null : packet.getMatch().getTunnel().getTunnelId();
            String interfaceName = getInterfaceNameFromTag(portTag);
            InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName);
            if (interfaceInfo == null) {
                LOG.error("Failed to get interface info for interface name {}", interfaceName);
                return;
            }
            Port port;
            if (tunnelId != null) {
                port = dhcpExternalTunnelManager.readVniMacToPortCache(tunnelId, macAddress);
            } else {
                port = getNeutronPort(interfaceName);
            }
            Subnet subnet = getNeutronSubnet(port);
            String serverMacAddress = interfaceInfo.getMacAddress();
            String serverIp = null;
            if (subnet != null) {
                java.util.Optional<SubnetToDhcpPort> dhcpPortData = DhcpServiceUtils.getSubnetDhcpPortData(broker, subnet.getUuid().getValue());
                /* If enable_dhcp_service flag was enabled and an ODL network DHCP Port data was made available use
                     * the ports Fixed IP as server IP for DHCP communication.
                     */
                if (dhcpPortData.isPresent()) {
                    serverIp = dhcpPortData.get().getPortFixedip();
                    serverMacAddress = dhcpPortData.get().getPortMacaddress();
                } else {
                    // DHCP Neutron Port not found for this network
                    LOG.error("Neutron DHCP port is not available for the Subnet {} and port {}.", subnet.getUuid(), port.getUuid());
                    return;
                }
            }
            DHCP replyPkt = handleDhcpPacket(pktIn, interfaceName, macAddress, port, subnet, serverIp);
            if (replyPkt == null) {
                LOG.warn("Unable to construct reply packet for interface name {}", interfaceName);
                return;
            }
            byte[] pktOut = getDhcpPacketOut(replyPkt, ethPkt, serverMacAddress);
            sendPacketOut(pktOut, interfaceInfo.getDpId(), interfaceName, tunnelId);
        }
    }
}
Also used : SubnetToDhcpPort(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPort) Port(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port) PacketException(org.opendaylight.openflowplugin.libraries.liblldp.PacketException) DHCP(org.opendaylight.netvirt.dhcpservice.api.DHCP) SubnetToDhcpPort(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPort) Ethernet(org.opendaylight.genius.mdsalutil.packet.Ethernet) BigInteger(java.math.BigInteger) InterfaceInfo(org.opendaylight.genius.interfacemanager.globals.InterfaceInfo) Subnet(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet)

Example 5 with DHCP

use of org.opendaylight.netvirt.dhcpservice.api.DHCP in project netvirt by opendaylight.

the class DhcpPktHandler method getReplyToDiscover.

DHCP getReplyToDiscover(DHCP dhcpPkt, DhcpInfo dhcpInfo) {
    DHCP reply = new DHCP();
    reply.setOp(DHCPConstants.BOOTREPLY);
    reply.setHtype(dhcpPkt.getHtype());
    reply.setHlen(dhcpPkt.getHlen());
    reply.setHops((byte) 0);
    reply.setXid(dhcpPkt.getXid());
    reply.setSecs((short) 0);
    reply.setYiaddr(dhcpInfo.getClientIp());
    reply.setSiaddr(dhcpInfo.getServerIp());
    reply.setFlags(dhcpPkt.getFlags());
    reply.setGiaddr(dhcpPkt.getGiaddr());
    reply.setChaddr(dhcpPkt.getChaddr());
    reply.setMsgType(DHCPConstants.MSG_OFFER);
    if (dhcpPkt.containsOption(DHCPConstants.OPT_PARAMETER_REQUEST_LIST)) {
        setParameterListOptions(dhcpPkt, reply, dhcpInfo);
    }
    setCommonOptions(reply, dhcpInfo);
    return reply;
}
Also used : DHCP(org.opendaylight.netvirt.dhcpservice.api.DHCP)

Aggregations

DHCP (org.opendaylight.netvirt.dhcpservice.api.DHCP)5 Ethernet (org.opendaylight.genius.mdsalutil.packet.Ethernet)2 PacketException (org.opendaylight.openflowplugin.libraries.liblldp.PacketException)2 BigInteger (java.math.BigInteger)1 UnknownHostException (java.net.UnknownHostException)1 InterfaceInfo (org.opendaylight.genius.interfacemanager.globals.InterfaceInfo)1 IPv4 (org.opendaylight.genius.mdsalutil.packet.IPv4)1 UDP (org.opendaylight.genius.mdsalutil.packet.UDP)1 Port (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port)1 Subnet (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet)1 SubnetToDhcpPort (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPort)1