2 * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.vpnservice.dhcpservice;
10 import java.io.ByteArrayOutputStream;
11 import java.io.IOException;
12 import java.math.BigInteger;
13 import java.net.InetAddress;
14 import java.net.UnknownHostException;
15 import java.util.Arrays;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Future;
21 import org.apache.commons.lang3.tuple.ImmutablePair;
22 import org.apache.commons.net.util.SubnetUtils;
23 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
24 import org.opendaylight.controller.liblldp.EtherTypes;
25 import org.opendaylight.controller.liblldp.NetUtils;
26 import org.opendaylight.controller.liblldp.PacketException;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.vpnservice.dhcpservice.api.DHCP;
30 import org.opendaylight.vpnservice.dhcpservice.api.DHCPConstants;
31 import org.opendaylight.vpnservice.dhcpservice.api.DHCPMConstants;
32 import org.opendaylight.vpnservice.dhcpservice.api.DHCPUtils;
33 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
34 import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
35 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
36 import org.opendaylight.vpnservice.mdsalutil.packet.Ethernet;
37 import org.opendaylight.vpnservice.mdsalutil.packet.IEEE8021Q;
38 import org.opendaylight.vpnservice.mdsalutil.packet.IPProtocols;
39 import org.opendaylight.vpnservice.mdsalutil.packet.IPv4;
40 import org.opendaylight.vpnservice.mdsalutil.packet.UDP;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnet.attributes.HostRoutes;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketInReason;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.SendToController;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetInterfaceFromIfIndexInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetInterfaceFromIfIndexInputBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetInterfaceFromIfIndexOutput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
60 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
61 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
62 import org.opendaylight.yangtools.yang.common.RpcResult;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
66 import com.google.common.base.Optional;
68 public class DhcpPktHandler implements AutoCloseable, PacketProcessingListener {
70 private static final Logger LOG = LoggerFactory.getLogger(DhcpPktHandler.class);
71 private final DataBroker dataBroker;
72 private final DhcpManager dhcpMgr;
73 private OdlInterfaceRpcService interfaceManagerRpc;
74 private boolean computeUdpChecksum = true;
75 private PacketProcessingService pktService;
76 private DhcpExternalTunnelManager dhcpExternalTunnelManager;
78 public DhcpPktHandler(final DataBroker broker, final DhcpManager dhcpManager, final DhcpExternalTunnelManager dhcpExternalTunnelManager) {
79 this.dhcpExternalTunnelManager = dhcpExternalTunnelManager;
80 this.dataBroker = broker;
81 dhcpMgr = dhcpManager;
84 //TODO: Handle this in a separate thread
86 public void onPacketReceived(PacketReceived packet) {
87 Class<? extends PacketInReason> pktInReason = packet.getPacketInReason();
88 if (isPktInReasonSendtoCtrl(pktInReason)) {
89 byte[] inPayload = packet.getPayload();
90 Ethernet ethPkt = new Ethernet();
92 ethPkt.deserialize(inPayload, 0, inPayload.length * NetUtils.NumBitsInAByte);
93 } catch (Exception e) {
94 LOG.warn("Failed to decode DHCP Packet {}", e);
95 LOG.trace("Received packet {}", packet);
100 pktIn = getDhcpPktIn(ethPkt);
102 LOG.trace("DHCPPkt received: {}", pktIn);
103 LOG.trace("Received Packet: {}", packet);
104 BigInteger metadata = packet.getMatch().getMetadata().getMetadata();
105 long portTag = MetaDataUtil.getLportFromMetadata(metadata).intValue();
106 String macAddress = DHCPUtils.byteArrayToString(ethPkt.getSourceMACAddress());
107 BigInteger tunnelId = packet.getMatch().getTunnel() == null ? null : packet.getMatch().getTunnel().getTunnelId();
108 String interfaceName = getInterfaceNameFromTag(portTag);
109 ImmutablePair<BigInteger, String> pair = getDpnIdPhysicalAddressFromInterfaceName(interfaceName);
110 DHCP replyPkt = handleDhcpPacket(pktIn, interfaceName, macAddress, tunnelId);
111 byte[] pktOut = getDhcpPacketOut(replyPkt, ethPkt, pair.getRight());
112 sendPacketOut(pktOut, pair.getLeft(), interfaceName, tunnelId);
114 } catch (Exception e) {
115 LOG.warn("Failed to get DHCP Reply");
116 LOG.trace("Reason for failure {}", e);
121 private void sendPacketOut(byte[] pktOut, BigInteger dpnId, String interfaceName, BigInteger tunnelId) {
122 LOG.trace("Sending packet out DpId {}, portId {}, vlanId {}, interfaceName {}", dpnId, interfaceName);
123 List<Action> action = getEgressAction(interfaceName, tunnelId);
124 TransmitPacketInput output = MDSALUtil.getPacketOut(action, pktOut, dpnId);
125 LOG.trace("Transmitting packet: {}",output);
126 this.pktService.transmitPacket(output);
129 private DHCP handleDhcpPacket(DHCP dhcpPkt, String interfaceName, String macAddress, BigInteger tunnelId) {
130 LOG.debug("DHCP pkt rcvd {}", dhcpPkt);
131 byte msgType = dhcpPkt.getMsgType();
132 if (msgType == DHCPConstants.MSG_DECLINE) {
133 LOG.debug("DHCPDECLINE received");
135 } else if (msgType == DHCPConstants.MSG_RELEASE) {
136 LOG.debug("DHCPRELEASE received");
140 if (tunnelId != null) {
141 nPort = dhcpExternalTunnelManager.readVniMacToPortCache(tunnelId, macAddress);
143 nPort = getNeutronPort(interfaceName);
145 Subnet nSubnet = getNeutronSubnet(nPort);
146 DhcpInfo dhcpInfo = getDhcpInfo(nPort, nSubnet);
147 LOG.trace("NeutronPort: {} \n NeutronSubnet: {}, dhcpInfo{}",nPort, nSubnet, dhcpInfo);
149 if (dhcpInfo != null) {
150 if (msgType == DHCPConstants.MSG_DISCOVER) {
151 reply = getReplyToDiscover(dhcpPkt, dhcpInfo);
152 } else if (msgType == DHCPConstants.MSG_REQUEST) {
153 reply = getReplyToRequest(dhcpPkt, dhcpInfo);
160 private DhcpInfo getDhcpInfo(Port nPort, Subnet nSubnet) {
161 DhcpInfo dhcpInfo = null;
162 if( (nPort != null) && (nSubnet != null) ) {
163 String clientIp = nPort.getFixedIps().get(0).getIpAddress().getIpv4Address().getValue();
164 String serverIp = nSubnet.getGatewayIp().getIpv4Address().getValue();
165 List<IpAddress> dnsServers = nSubnet.getDnsNameservers();
166 dhcpInfo = new DhcpInfo();
167 dhcpInfo.setClientIp(clientIp).setServerIp(serverIp)
168 .setCidr(String.valueOf(nSubnet.getCidr().getValue()))
169 .setHostRoutes(nSubnet.getHostRoutes())
170 .setDnsServersIpAddrs(dnsServers).setGatewayIp(serverIp);
175 private Subnet getNeutronSubnet(Port nPort) {
176 return dhcpMgr.getNeutronSubnet(nPort);
179 private Port getNeutronPort(String interfaceName) {
180 return dhcpMgr.getNeutronPort(interfaceName);
183 private DHCP getDhcpPktIn(Ethernet actualEthernetPacket) {
184 Ethernet ethPkt = actualEthernetPacket;
185 if (ethPkt.getEtherType() == (short)NwConstants.ETHTYPE_802_1Q) {
186 ethPkt = (Ethernet)ethPkt.getPayload();
188 if (ethPkt.getPayload() instanceof IPv4) {
189 IPv4 ipPkt = (IPv4) ethPkt.getPayload();
190 if (ipPkt.getPayload() instanceof UDP) {
191 UDP udpPkt = (UDP) ipPkt.getPayload();
192 if ((udpPkt.getSourcePort() == DHCPMConstants.dhcpClientPort)
193 && (udpPkt.getDestinationPort() == DHCPMConstants.dhcpServerPort)) {
194 LOG.trace("Matched dhcpClientPort and dhcpServerPort");
195 byte[] rawDhcpPayload = udpPkt.getRawPayload();
196 DHCP reply = new DHCP();
198 reply.deserialize(rawDhcpPayload, 0, rawDhcpPayload.length);
199 } catch (PacketException e) {
200 LOG.warn("Failed to deserialize DHCP pkt");
201 LOG.trace("Reason for failure {}", e);
211 DHCP getReplyToDiscover(DHCP dhcpPkt, DhcpInfo dhcpInfo) {
212 DHCP reply = new DHCP();
213 reply.setOp(DHCPConstants.BOOTREPLY);
214 reply.setHtype(dhcpPkt.getHtype());
215 reply.setHlen(dhcpPkt.getHlen());
216 reply.setHops((byte) 0);
217 reply.setXid(dhcpPkt.getXid());
218 reply.setSecs((short) 0);
220 reply.setYiaddr(dhcpInfo.getClientIp());
221 reply.setSiaddr(dhcpInfo.getServerIp());
223 reply.setFlags(dhcpPkt.getFlags());
224 reply.setGiaddr(dhcpPkt.getGiaddr());
225 reply.setChaddr(dhcpPkt.getChaddr());
227 reply.setMsgType(DHCPConstants.MSG_OFFER);
228 if(dhcpPkt.containsOption(DHCPConstants.OPT_PARAMETER_REQUEST_LIST)) {
229 setParameterListOptions(dhcpPkt, reply, dhcpInfo);
231 setCommonOptions(reply, dhcpInfo);
235 DHCP getReplyToRequest(DHCP dhcpPkt, DhcpInfo dhcpInfo) {
236 boolean sendAck = false;
237 byte[] requestedIp = null;
238 DHCP reply = new DHCP();
239 reply.setOp(DHCPConstants.BOOTREPLY);
240 reply.setHtype(dhcpPkt.getHtype());
241 reply.setHlen(dhcpPkt.getHlen());
242 reply.setHops((byte) 0);
243 reply.setXid(dhcpPkt.getXid());
244 reply.setSecs((short) 0);
246 reply.setFlags(dhcpPkt.getFlags());
247 reply.setGiaddr(dhcpPkt.getGiaddr());
248 reply.setChaddr(dhcpPkt.getChaddr());
249 byte[] allocatedIp = DHCPUtils.strAddrToByteArray(dhcpInfo.getClientIp());
250 if(Arrays.equals(allocatedIp, dhcpPkt.getCiaddr())) {
251 //This means a renew request
254 requestedIp = dhcpPkt.getOptionBytes(DHCPConstants.OPT_REQUESTED_ADDRESS);
255 sendAck = Arrays.equals(allocatedIp, requestedIp);
259 reply.setCiaddr(dhcpPkt.getCiaddr());
260 reply.setYiaddr(dhcpInfo.getClientIp());
261 reply.setSiaddr(dhcpInfo.getServerIp());
262 reply.setMsgType(DHCPConstants.MSG_ACK);
263 if(dhcpPkt.containsOption(DHCPConstants.OPT_PARAMETER_REQUEST_LIST)) {
264 setParameterListOptions(dhcpPkt, reply, dhcpInfo);
266 setCommonOptions(reply, dhcpInfo);
269 reply.setMsgType(DHCPConstants.MSG_NAK);
274 protected byte[] getDhcpPacketOut(DHCP reply, Ethernet etherPkt, String phyAddrees) {
277 * DECLINE or RELEASE don't result in reply packet
281 LOG.debug("Sending DHCP Pkt {}", reply);
283 UDP udpPkt = new UDP();
286 rawPkt = reply.serialize();
287 } catch (PacketException e2) {
288 // TODO Auto-generated catch block
289 e2.printStackTrace();
292 udpPkt.setRawPayload(rawPkt);
293 udpPkt.setDestinationPort(DHCPMConstants.dhcpClientPort);
294 udpPkt.setSourcePort(DHCPMConstants.dhcpServerPort);
295 udpPkt.setLength((short) (rawPkt.length + 8));
297 IPv4 ip4Reply = new IPv4();
299 rawPkt = udpPkt.serialize();
300 } catch (PacketException e) {
301 // TODO Auto-generated catch block
306 if(this.computeUdpChecksum) {
307 checkSum = computeChecksum(rawPkt, reply.getSiaddr(),
308 NetUtils.intToByteArray4(DHCPMConstants.BCAST_IP));
310 udpPkt.setChecksum(checkSum);
311 ip4Reply.setPayload(udpPkt);
312 ip4Reply.setProtocol(IPProtocols.UDP.byteValue());
313 ip4Reply.setSourceAddress(reply.getSiaddrAsInetAddr());
314 ip4Reply.setDestinationAddress(DHCPMConstants.BCAST_IP);
315 ip4Reply.setTotalLength((short) (rawPkt.length+20));
316 ip4Reply.setTtl((byte) 32);
317 // create Ethernet Frame
318 Ethernet ether = new Ethernet();
319 if (etherPkt.getEtherType() == (short)NwConstants.ETHTYPE_802_1Q) {
320 IEEE8021Q vlanPacket = (IEEE8021Q) etherPkt.getPayload();
321 IEEE8021Q vlanTagged = new IEEE8021Q();
322 vlanTagged.setCFI(vlanPacket.getCfi());
323 vlanTagged.setPriority(vlanPacket.getPriority());
324 vlanTagged.setVlanId(vlanPacket.getVlanId());
325 vlanTagged.setPayload(ip4Reply);
326 vlanTagged.setEtherType(EtherTypes.IPv4.shortValue());
327 ether.setPayload(vlanTagged);
328 ether.setEtherType((short) NwConstants.ETHTYPE_802_1Q);
330 ether.setEtherType(EtherTypes.IPv4.shortValue());
331 ether.setPayload(ip4Reply);
333 ether.setSourceMACAddress(getServerMacAddress(phyAddrees));
334 ether.setDestinationMACAddress(etherPkt.getSourceMACAddress());
337 rawPkt = ether.serialize();
338 } catch (PacketException e) {
339 LOG.warn("Failed to serialize ethernet reply",e);
345 private byte[] getServerMacAddress(String phyAddress) {
346 // Should we return ControllerMac instead?
347 return DHCPUtils.strMacAddrtoByteArray(phyAddress);
350 public short computeChecksum(byte[] inData, byte[] srcAddr, byte[] destAddr) {
351 short checkSum = (short) 0;
352 int sum = 0, carry = 0;
355 for (i = 0; i < inData.length - 1; i = i + 2) {
356 // Skip, if the current bytes are checkSum bytes
357 wordData = ((inData[i] << 8) & 0xFF00) + (inData[i + 1] & 0xFF);
358 sum = sum + wordData;
361 if (i < inData.length) {
362 wordData = ((inData[i] << 8) & 0xFF00) + (0 & 0xFF);
363 sum = sum + wordData;
366 for (i = 0; i < 4; i = i + 2) {
367 wordData = ((srcAddr[i] << 8) & 0xFF00) + (srcAddr[i + 1] & 0xFF);
368 sum = sum + wordData;
371 for (i = 0; i < 4; i = i + 2) {
372 wordData = ((destAddr[i] << 8) & 0xFF00) + (destAddr[i + 1] & 0xFF);
373 sum = sum + wordData;
375 sum = sum + 17 + inData.length;
377 while((sum >> 16) != 0) {
379 sum = (sum & 0xFFFF)+ carry;
381 checkSum = (short) ~((short) sum & 0xFFFF);
383 checkSum = (short)0xffff;
388 private void setCommonOptions(DHCP pkt, DhcpInfo dhcpInfo) {
389 pkt.setOptionInt(DHCPConstants.OPT_LEASE_TIME, dhcpMgr.getDhcpLeaseTime());
390 if (dhcpMgr.getDhcpDefDomain() != null) {
391 pkt.setOptionString(DHCPConstants.OPT_DOMAIN_NAME, dhcpMgr.getDhcpDefDomain());
393 if(dhcpMgr.getDhcpLeaseTime() > 0) {
394 pkt.setOptionInt(DHCPConstants.OPT_REBINDING_TIME, dhcpMgr.getDhcpRebindingTime());
395 pkt.setOptionInt(DHCPConstants.OPT_RENEWAL_TIME, dhcpMgr.getDhcpRenewalTime());
397 SubnetUtils util = null;
398 SubnetInfo info = null;
399 util = new SubnetUtils(dhcpInfo.getCidr());
400 info = util.getInfo();
401 String gwIp = dhcpInfo.getGatewayIp();
402 List<String> dnServers = dhcpInfo.getDnsServers();
405 * setParameterListOptions may have initialized some of these
406 * options to maintain order. If we can't fill them, unset to avoid
407 * sending wrong information in reply.
410 pkt.setOptionInetAddr(DHCPConstants.OPT_SERVER_IDENTIFIER, gwIp);
411 pkt.setOptionInetAddr(DHCPConstants.OPT_ROUTERS, gwIp);
413 pkt.unsetOption(DHCPConstants.OPT_SERVER_IDENTIFIER);
414 pkt.unsetOption(DHCPConstants.OPT_ROUTERS);
417 pkt.setOptionInetAddr(DHCPConstants.OPT_SUBNET_MASK, info.getNetmask());
418 pkt.setOptionInetAddr(DHCPConstants.OPT_BROADCAST_ADDRESS, info.getBroadcastAddress());
420 pkt.unsetOption(DHCPConstants.OPT_SUBNET_MASK);
421 pkt.unsetOption(DHCPConstants.OPT_BROADCAST_ADDRESS);
423 if ((dnServers != null) && (dnServers.size() > 0)) {
424 pkt.setOptionStrAddrs(DHCPConstants.OPT_DOMAIN_NAME_SERVERS, dnServers);
426 pkt.unsetOption(DHCPConstants.OPT_DOMAIN_NAME_SERVERS);
428 } catch (UnknownHostException e) {
429 // TODO Auto-generated catch block
434 private void setParameterListOptions(DHCP req, DHCP reply, DhcpInfo dhcpInfo) {
435 byte[] paramList = req.getOptionBytes(DHCPConstants.OPT_PARAMETER_REQUEST_LIST);
436 for(int i = 0; i < paramList.length; i++) {
437 switch (paramList[i]) {
438 case DHCPConstants.OPT_SUBNET_MASK:
439 case DHCPConstants.OPT_ROUTERS:
440 case DHCPConstants.OPT_SERVER_IDENTIFIER:
441 case DHCPConstants.OPT_DOMAIN_NAME_SERVERS:
442 case DHCPConstants.OPT_BROADCAST_ADDRESS:
443 case DHCPConstants.OPT_LEASE_TIME:
444 case DHCPConstants.OPT_RENEWAL_TIME:
445 case DHCPConstants.OPT_REBINDING_TIME:
446 /* These values will be filled in setCommonOptions
447 * Setting these just to preserve order as
448 * specified in PARAMETER_REQUEST_LIST.
450 reply.setOptionInt(paramList[i], 0);
452 case DHCPConstants.OPT_DOMAIN_NAME:
453 reply.setOptionString(paramList[i], " ");
455 case DHCPConstants.OPT_CLASSLESS_ROUTE:
456 setOptionClasslessRoute(reply, dhcpInfo);
459 LOG.debug("DHCP Option code {} not supported yet", paramList[i]);
464 private void setOptionClasslessRoute(DHCP reply, DhcpInfo dhcpInfo) {
465 List<HostRoutes> hostRoutes = dhcpInfo.getHostRoutes();
466 if(hostRoutes == null) {
467 //we can't set this option, so return
470 ByteArrayOutputStream result = new ByteArrayOutputStream();
471 Iterator<HostRoutes> iter = hostRoutes.iterator();
472 while(iter.hasNext()) {
473 HostRoutes hostRoute = iter.next();
474 if(hostRoute.getNexthop().getIpv4Address() == null ||
475 hostRoute.getDestination().getIpv4Prefix() == null ) {
476 // we only deal with IPv4 addresses
479 String router = hostRoute.getNexthop().getIpv4Address().getValue();
480 String dest = hostRoute.getDestination().getIpv4Prefix().getValue();
482 result.write(convertToClasslessRouteOption(dest, router));
483 } catch (IOException | NullPointerException e) {
484 LOG.debug("Exception {}",e.getMessage());
487 if (result.size() > 0) {
488 reply.setOptionBytes(DHCPConstants.OPT_CLASSLESS_ROUTE , result.toByteArray());
492 protected byte[] convertToClasslessRouteOption(String dest, String router) {
493 ByteArrayOutputStream bArr = new ByteArrayOutputStream();
501 String[] parts = dest.split("/");
502 if (parts.length < 2) {
503 prefix = new Short((short)0);
505 prefix = Short.valueOf(parts[1]);
508 bArr.write(prefix.byteValue());
509 SubnetUtils util = new SubnetUtils(dest);
510 SubnetInfo info = util.getInfo();
511 String strNetAddr = info.getNetworkAddress();
513 byte[] netAddr = InetAddress.getByName(strNetAddr).getAddress();
514 //Strip any trailing 0s from netAddr
515 for(int i = 0; i < netAddr.length;i++) {
516 if(netAddr[i] != 0) {
517 bArr.write(netAddr,i,1);
520 bArr.write(InetAddress.getByName(router).getAddress());
521 } catch (IOException e) {
524 return bArr.toByteArray();
527 private boolean isPktInReasonSendtoCtrl(Class<? extends PacketInReason> pktInReason) {
528 return (pktInReason == SendToController.class);
532 public void close() throws Exception {
533 // TODO Auto-generated method stub
536 public void setPacketProcessingService(PacketProcessingService packetService) {
537 this.pktService = packetService;
540 public void setInterfaceManagerRpc(OdlInterfaceRpcService interfaceManagerRpc) {
541 LOG.trace("Registered interfaceManager successfully");;
542 this.interfaceManagerRpc = interfaceManagerRpc;
545 private String getInterfaceNameFromTag(long portTag) {
546 String interfaceName = null;
547 GetInterfaceFromIfIndexInput input = new GetInterfaceFromIfIndexInputBuilder().setIfIndex(new Integer((int)portTag)).build();
548 Future<RpcResult<GetInterfaceFromIfIndexOutput>> futureOutput = interfaceManagerRpc.getInterfaceFromIfIndex(input);
550 GetInterfaceFromIfIndexOutput output = futureOutput.get().getResult();
551 interfaceName = output.getInterfaceName();
552 } catch (InterruptedException | ExecutionException e) {
553 LOG.error("Error while retrieving the interfaceName from tag using getInterfaceFromIfIndex RPC");
555 LOG.trace("Returning interfaceName {} for tag {} form getInterfaceNameFromTag", interfaceName, portTag);
556 return interfaceName;
559 private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(String interfaceName) {
560 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId =
561 buildStateInterfaceId(interfaceName);
562 Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional =
563 MDSALUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker);
564 if (!ifStateOptional.isPresent()) {
568 return ifStateOptional.get();
571 private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
572 InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
573 InstanceIdentifier.builder(InterfacesState.class)
574 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
575 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
576 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
580 private List<Action> getEgressAction(String interfaceName, BigInteger tunnelId) {
581 List<Action> actions = null;
583 GetEgressActionsForInterfaceInputBuilder egressAction = new GetEgressActionsForInterfaceInputBuilder().setIntfName(interfaceName);
584 if (tunnelId != null) {
585 egressAction.setTunnelKey(tunnelId.longValue());
587 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
588 interfaceManagerRpc.getEgressActionsForInterface(egressAction.build());
589 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
590 if(!rpcResult.isSuccessful()) {
591 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", interfaceName, rpcResult.getErrors());
593 actions = rpcResult.getResult().getAction();
595 } catch (InterruptedException | ExecutionException e) {
596 LOG.warn("Exception when egress actions for interface {}", interfaceName, e);
601 private ImmutablePair<BigInteger, String> getDpnIdPhysicalAddressFromInterfaceName(String interfaceName) {
602 ImmutablePair<BigInteger, String> pair = dhcpMgr.getInterfaceCache(interfaceName);
603 if (pair!=null && pair.getLeft() != null && pair.getRight() != null) {
606 NodeConnectorId nodeConnectorId = null;
607 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface interfaceState = getInterfaceStateFromOperDS(interfaceName);
608 if(interfaceState != null) {
609 List<String> ofportIds = interfaceState.getLowerLayerIf();
610 nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
612 BigInteger dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
613 String phyAddress = interfaceState==null ? "":interfaceState.getPhysAddress().getValue();
614 pair = new ImmutablePair<BigInteger, String>(dpId, phyAddress);
615 dhcpMgr.updateInterfaceCache(interfaceName, pair);