/* * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.vpnservice.dhcpservice; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.net.util.SubnetUtils; import org.apache.commons.net.util.SubnetUtils.SubnetInfo; import org.opendaylight.controller.liblldp.EtherTypes; import org.opendaylight.controller.liblldp.NetUtils; import org.opendaylight.controller.liblldp.PacketException; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.vpnservice.dhcpservice.api.DHCP; import org.opendaylight.vpnservice.dhcpservice.api.DHCPConstants; import org.opendaylight.vpnservice.dhcpservice.api.DHCPMConstants; import org.opendaylight.vpnservice.dhcpservice.api.DHCPUtils; import org.opendaylight.vpnservice.mdsalutil.MDSALUtil; import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil; import org.opendaylight.vpnservice.mdsalutil.NwConstants; import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet; import org.opendaylight.vpnservice.mdsalutil.packet.IEEE8021Q; import org.opendaylight.vpnservice.mdsalutil.packet.IPProtocols; import org.opendaylight.vpnservice.mdsalutil.packet.IPv4; import org.opendaylight.vpnservice.mdsalutil.packet.UDP; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnet.attributes.HostRoutes; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketInReason; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetInterfaceFromIfIndexInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetInterfaceFromIfIndexInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetInterfaceFromIfIndexOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Optional; public class DhcpPktHandler implements AutoCloseable, PacketProcessingListener { private static final Logger LOG = LoggerFactory.getLogger(DhcpPktHandler.class); private final DataBroker dataBroker; private final DhcpManager dhcpMgr; private OdlInterfaceRpcService interfaceManagerRpc; private boolean computeUdpChecksum = true; private PacketProcessingService pktService; private DhcpExternalTunnelManager dhcpExternalTunnelManager; public DhcpPktHandler(final DataBroker broker, final DhcpManager dhcpManager, final DhcpExternalTunnelManager dhcpExternalTunnelManager) { this.dhcpExternalTunnelManager = dhcpExternalTunnelManager; this.dataBroker = broker; dhcpMgr = dhcpManager; } //TODO: Handle this in a separate thread @Override public void onPacketReceived(PacketReceived packet) { Class pktInReason = packet.getPacketInReason(); if (isPktInReasonSendtoCtrl(pktInReason)) { byte[] inPayload = packet.getPayload(); Ethernet ethPkt = new Ethernet(); try { ethPkt.deserialize(inPayload, 0, inPayload.length * NetUtils.NumBitsInAByte); } catch (Exception e) { LOG.warn("Failed to decode DHCP Packet {}", e); LOG.trace("Received packet {}", packet); return; } try { 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); ImmutablePair pair = getDpnIdPhysicalAddressFromInterfaceName(interfaceName); DHCP replyPkt = handleDhcpPacket(pktIn, interfaceName, macAddress, tunnelId); byte[] pktOut = getDhcpPacketOut(replyPkt, ethPkt, pair.getRight()); sendPacketOut(pktOut, pair.getLeft(), interfaceName, tunnelId); } } catch (Exception e) { LOG.warn("Failed to get DHCP Reply"); LOG.trace("Reason for failure {}", e); } } } private void sendPacketOut(byte[] pktOut, BigInteger dpnId, String interfaceName, BigInteger tunnelId) { LOG.trace("Sending packet out DpId {}, portId {}, vlanId {}, interfaceName {}", dpnId, interfaceName); List action = getEgressAction(interfaceName, tunnelId); TransmitPacketInput output = MDSALUtil.getPacketOut(action, pktOut, dpnId); LOG.trace("Transmitting packet: {}",output); this.pktService.transmitPacket(output); } private DHCP handleDhcpPacket(DHCP dhcpPkt, String interfaceName, String macAddress, BigInteger tunnelId) { LOG.debug("DHCP pkt rcvd {}", dhcpPkt); byte msgType = dhcpPkt.getMsgType(); if (msgType == DHCPConstants.MSG_DECLINE) { LOG.debug("DHCPDECLINE received"); return null; } else if (msgType == DHCPConstants.MSG_RELEASE) { LOG.debug("DHCPRELEASE received"); return null; } Port nPort; if (tunnelId != null) { nPort = dhcpExternalTunnelManager.readVniMacToPortCache(tunnelId, macAddress); } else { nPort = getNeutronPort(interfaceName); } Subnet nSubnet = getNeutronSubnet(nPort); DhcpInfo dhcpInfo = getDhcpInfo(nPort, nSubnet); LOG.trace("NeutronPort: {} \n NeutronSubnet: {}, dhcpInfo{}",nPort, nSubnet, dhcpInfo); 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; } private DhcpInfo getDhcpInfo(Port nPort, Subnet nSubnet) { DhcpInfo dhcpInfo = null; if( (nPort != null) && (nSubnet != null) ) { String clientIp = nPort.getFixedIps().get(0).getIpAddress().getIpv4Address().getValue(); String serverIp = nSubnet.getGatewayIp().getIpv4Address().getValue(); List dnsServers = nSubnet.getDnsNameservers(); dhcpInfo = new DhcpInfo(); dhcpInfo.setClientIp(clientIp).setServerIp(serverIp) .setCidr(String.valueOf(nSubnet.getCidr().getValue())) .setHostRoutes(nSubnet.getHostRoutes()) .setDnsServersIpAddrs(dnsServers).setGatewayIp(serverIp); } return dhcpInfo; } private Subnet getNeutronSubnet(Port nPort) { return dhcpMgr.getNeutronSubnet(nPort); } private Port getNeutronPort(String interfaceName) { return dhcpMgr.getNeutronPort(interfaceName); } private DHCP getDhcpPktIn(Ethernet actualEthernetPacket) { Ethernet ethPkt = actualEthernetPacket; if (ethPkt.getEtherType() == (short)NwConstants.ETHTYPE_802_1Q) { ethPkt = (Ethernet)ethPkt.getPayload(); } if (ethPkt.getPayload() instanceof IPv4) { IPv4 ipPkt = (IPv4) ethPkt.getPayload(); if (ipPkt.getPayload() instanceof UDP) { UDP udpPkt = (UDP) ipPkt.getPayload(); if ((udpPkt.getSourcePort() == DHCPMConstants.dhcpClientPort) && (udpPkt.getDestinationPort() == DHCPMConstants.dhcpServerPort)) { LOG.trace("Matched dhcpClientPort and dhcpServerPort"); 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; } 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; } 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 = DHCPUtils.strAddrToByteArray(dhcpInfo.getClientIp()); 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); } setCommonOptions(reply, dhcpInfo); } else { reply.setMsgType(DHCPConstants.MSG_NAK); } return reply; } protected byte[] getDhcpPacketOut(DHCP reply, Ethernet etherPkt, String phyAddrees) { if (reply == null) { /* * DECLINE or RELEASE don't result in reply packet */ return null; } LOG.debug("Sending DHCP Pkt {}", reply); // create UDP pkt UDP udpPkt = new UDP(); byte[] rawPkt; try { rawPkt = reply.serialize(); } catch (PacketException e2) { // TODO Auto-generated catch block e2.printStackTrace(); return null; } udpPkt.setRawPayload(rawPkt); udpPkt.setDestinationPort(DHCPMConstants.dhcpClientPort); udpPkt.setSourcePort(DHCPMConstants.dhcpServerPort); udpPkt.setLength((short) (rawPkt.length + 8)); //Create IP Pkt IPv4 ip4Reply = new IPv4(); try { rawPkt = udpPkt.serialize(); } catch (PacketException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } short checkSum = 0; if(this.computeUdpChecksum) { checkSum = computeChecksum(rawPkt, reply.getSiaddr(), NetUtils.intToByteArray4(DHCPMConstants.BCAST_IP)); } udpPkt.setChecksum(checkSum); ip4Reply.setPayload(udpPkt); ip4Reply.setProtocol(IPProtocols.UDP.byteValue()); ip4Reply.setSourceAddress(reply.getSiaddrAsInetAddr()); 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; } private byte[] getServerMacAddress(String phyAddress) { // Should we return ControllerMac instead? return DHCPUtils.strMacAddrtoByteArray(phyAddress); } public short computeChecksum(byte[] inData, byte[] srcAddr, byte[] destAddr) { short checkSum = (short) 0; int sum = 0, carry = 0; int wordData, i; for (i = 0; i < inData.length - 1; i = i + 2) { // Skip, if the current bytes are checkSum bytes wordData = ((inData[i] << 8) & 0xFF00) + (inData[i + 1] & 0xFF); sum = sum + wordData; } if (i < inData.length) { wordData = ((inData[i] << 8) & 0xFF00) + (0 & 0xFF); sum = sum + wordData; } for (i = 0; i < 4; i = i + 2) { wordData = ((srcAddr[i] << 8) & 0xFF00) + (srcAddr[i + 1] & 0xFF); sum = sum + wordData; } for (i = 0; i < 4; i = i + 2) { wordData = ((destAddr[i] << 8) & 0xFF00) + (destAddr[i + 1] & 0xFF); sum = sum + wordData; } sum = sum + 17 + inData.length; while((sum >> 16) != 0) { carry = (sum >> 16); sum = (sum & 0xFFFF)+ carry; } checkSum = (short) ~((short) sum & 0xFFFF); if(checkSum == 0) { checkSum = (short)0xffff; } return checkSum; } private void setCommonOptions(DHCP pkt, DhcpInfo dhcpInfo) { pkt.setOptionInt(DHCPConstants.OPT_LEASE_TIME, dhcpMgr.getDhcpLeaseTime()); if (dhcpMgr.getDhcpDefDomain() != null) { pkt.setOptionString(DHCPConstants.OPT_DOMAIN_NAME, dhcpMgr.getDhcpDefDomain()); } if(dhcpMgr.getDhcpLeaseTime() > 0) { pkt.setOptionInt(DHCPConstants.OPT_REBINDING_TIME, dhcpMgr.getDhcpRebindingTime()); pkt.setOptionInt(DHCPConstants.OPT_RENEWAL_TIME, dhcpMgr.getDhcpRenewalTime()); } SubnetUtils util = null; SubnetInfo info = null; util = new SubnetUtils(dhcpInfo.getCidr()); info = util.getInfo(); String gwIp = dhcpInfo.getGatewayIp(); List dnServers = dhcpInfo.getDnsServers(); try { /* * setParameterListOptions may have initialized some of these * options to maintain order. If we can't fill them, unset to avoid * sending wrong information in reply. */ if (gwIp != null) { pkt.setOptionInetAddr(DHCPConstants.OPT_SERVER_IDENTIFIER, gwIp); pkt.setOptionInetAddr(DHCPConstants.OPT_ROUTERS, gwIp); } else { pkt.unsetOption(DHCPConstants.OPT_SERVER_IDENTIFIER); pkt.unsetOption(DHCPConstants.OPT_ROUTERS); } if (info != null) { pkt.setOptionInetAddr(DHCPConstants.OPT_SUBNET_MASK, info.getNetmask()); pkt.setOptionInetAddr(DHCPConstants.OPT_BROADCAST_ADDRESS, info.getBroadcastAddress()); } else { pkt.unsetOption(DHCPConstants.OPT_SUBNET_MASK); pkt.unsetOption(DHCPConstants.OPT_BROADCAST_ADDRESS); } if ((dnServers != null) && (dnServers.size() > 0)) { pkt.setOptionStrAddrs(DHCPConstants.OPT_DOMAIN_NAME_SERVERS, dnServers); } else { pkt.unsetOption(DHCPConstants.OPT_DOMAIN_NAME_SERVERS); } } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void setParameterListOptions(DHCP req, DHCP reply, DhcpInfo dhcpInfo) { byte[] paramList = req.getOptionBytes(DHCPConstants.OPT_PARAMETER_REQUEST_LIST); for(int i = 0; i < paramList.length; i++) { switch (paramList[i]) { case DHCPConstants.OPT_SUBNET_MASK: case DHCPConstants.OPT_ROUTERS: case DHCPConstants.OPT_SERVER_IDENTIFIER: case DHCPConstants.OPT_DOMAIN_NAME_SERVERS: case DHCPConstants.OPT_BROADCAST_ADDRESS: case DHCPConstants.OPT_LEASE_TIME: case DHCPConstants.OPT_RENEWAL_TIME: case DHCPConstants.OPT_REBINDING_TIME: /* These values will be filled in setCommonOptions * Setting these just to preserve order as * specified in PARAMETER_REQUEST_LIST. */ reply.setOptionInt(paramList[i], 0); break; case DHCPConstants.OPT_DOMAIN_NAME: reply.setOptionString(paramList[i], " "); break; case DHCPConstants.OPT_CLASSLESS_ROUTE: setOptionClasslessRoute(reply, dhcpInfo); break; default: LOG.debug("DHCP Option code {} not supported yet", paramList[i]); break; } } } private void setOptionClasslessRoute(DHCP reply, DhcpInfo dhcpInfo) { List hostRoutes = dhcpInfo.getHostRoutes(); if(hostRoutes == null) { //we can't set this option, so return return; } ByteArrayOutputStream result = new ByteArrayOutputStream(); Iterator iter = hostRoutes.iterator(); while(iter.hasNext()) { HostRoutes hostRoute = iter.next(); if(hostRoute.getNexthop().getIpv4Address() == null || hostRoute.getDestination().getIpv4Prefix() == null ) { // we only deal with IPv4 addresses return; } String router = hostRoute.getNexthop().getIpv4Address().getValue(); String dest = hostRoute.getDestination().getIpv4Prefix().getValue(); try { result.write(convertToClasslessRouteOption(dest, router)); } catch (IOException | NullPointerException e) { LOG.debug("Exception {}",e.getMessage()); } } if (result.size() > 0) { reply.setOptionBytes(DHCPConstants.OPT_CLASSLESS_ROUTE , result.toByteArray()); } } protected byte[] convertToClasslessRouteOption(String dest, String router) { ByteArrayOutputStream bArr = new ByteArrayOutputStream(); if((dest == null || router == null)) { return null; } //get prefix Short prefix = null; String[] parts = dest.split("/"); if (parts.length < 2) { prefix = new Short((short)0); } else { prefix = Short.valueOf(parts[1]); } bArr.write(prefix.byteValue()); SubnetUtils util = new SubnetUtils(dest); SubnetInfo info = util.getInfo(); String strNetAddr = info.getNetworkAddress(); try { byte[] netAddr = InetAddress.getByName(strNetAddr).getAddress(); //Strip any trailing 0s from netAddr for(int i = 0; i < netAddr.length;i++) { if(netAddr[i] != 0) { bArr.write(netAddr,i,1); } } bArr.write(InetAddress.getByName(router).getAddress()); } catch (IOException e) { return null; } return bArr.toByteArray(); } private boolean isPktInReasonSendtoCtrl(Class pktInReason) { return (pktInReason == SendToController.class); } @Override public void close() throws Exception { // TODO Auto-generated method stub } public void setPacketProcessingService(PacketProcessingService packetService) { this.pktService = packetService; } public void setInterfaceManagerRpc(OdlInterfaceRpcService interfaceManagerRpc) { LOG.trace("Registered interfaceManager successfully");; this.interfaceManagerRpc = interfaceManagerRpc; } private String getInterfaceNameFromTag(long portTag) { String interfaceName = null; GetInterfaceFromIfIndexInput input = new GetInterfaceFromIfIndexInputBuilder().setIfIndex(new Integer((int)portTag)).build(); Future> futureOutput = interfaceManagerRpc.getInterfaceFromIfIndex(input); try { GetInterfaceFromIfIndexOutput output = futureOutput.get().getResult(); interfaceName = output.getInterfaceName(); } catch (InterruptedException | ExecutionException e) { LOG.error("Error while retrieving the interfaceName from tag using getInterfaceFromIfIndex RPC"); } LOG.trace("Returning interfaceName {} for tag {} form getInterfaceNameFromTag", interfaceName, portTag); return interfaceName; } private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(String interfaceName) { InstanceIdentifier ifStateId = buildStateInterfaceId(interfaceName); Optional ifStateOptional = MDSALUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker); if (!ifStateOptional.isPresent()) { return null; } return ifStateOptional.get(); } private InstanceIdentifier buildStateInterfaceId(String interfaceName) { InstanceIdentifierBuilder idBuilder = InstanceIdentifier.builder(InterfacesState.class) .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class, new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName)); InstanceIdentifier id = idBuilder.build(); return id; } private List getEgressAction(String interfaceName, BigInteger tunnelId) { List actions = null; try { GetEgressActionsForInterfaceInputBuilder egressAction = new GetEgressActionsForInterfaceInputBuilder().setIntfName(interfaceName); if (tunnelId != null) { egressAction.setTunnelKey(tunnelId.longValue()); } Future> result = interfaceManagerRpc.getEgressActionsForInterface(egressAction.build()); RpcResult rpcResult = result.get(); if(!rpcResult.isSuccessful()) { LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", interfaceName, rpcResult.getErrors()); } else { actions = rpcResult.getResult().getAction(); } } catch (InterruptedException | ExecutionException e) { LOG.warn("Exception when egress actions for interface {}", interfaceName, e); } return actions; } private ImmutablePair getDpnIdPhysicalAddressFromInterfaceName(String interfaceName) { ImmutablePair pair = dhcpMgr.getInterfaceCache(interfaceName); if (pair!=null && pair.getLeft() != null && pair.getRight() != null) { return pair; } NodeConnectorId nodeConnectorId = null; org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceState = getInterfaceStateFromOperDS(interfaceName); if(interfaceState != null) { List ofportIds = interfaceState.getLowerLayerIf(); nodeConnectorId = new NodeConnectorId(ofportIds.get(0)); } BigInteger dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId)); String phyAddress = interfaceState==null ? "":interfaceState.getPhysAddress().getValue(); pair = new ImmutablePair(dpId, phyAddress); dhcpMgr.updateInterfaceCache(interfaceName, pair); return pair; } }