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;
}
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;
}
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;
}
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);
}
}
}
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;
}
Aggregations