import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;
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.rev100924.IpAddress;
+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;
private final DataBroker dataBroker;
private final DhcpManager dhcpMgr;
private OdlInterfaceRpcService interfaceManagerRpc;
- private static HashMap<String, ImmutablePair<BigInteger, String>> localCache = new HashMap<String, ImmutablePair<BigInteger, String>>();
private boolean computeUdpChecksum = true;
private PacketProcessingService pktService;
+ private DhcpExternalTunnelManager dhcpExternalTunnelManager;
- public DhcpPktHandler(final DataBroker broker, final DhcpManager dhcpManager) {
+ 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) {
- LOG.trace("Pkt received: {}", packet);
Class<? extends PacketInReason> pktInReason = packet.getPacketInReason();
- short tableId = packet.getTableId().getValue();
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.warn("Failed to decode DHCP Packet {}", e);
+ LOG.trace("Received packet {}", packet);
return;
}
try {
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<BigInteger, String> pair = getDpnIdPhysicalAddressFromInterfaceName(interfaceName);
- DHCP replyPkt = handleDhcpPacket(pktIn, interfaceName);
+ DHCP replyPkt = handleDhcpPacket(pktIn, interfaceName, macAddress, tunnelId);
byte[] pktOut = getDhcpPacketOut(replyPkt, ethPkt, pair.getRight());
- sendPacketOut(pktOut, pair.getLeft(), interfaceName);
+ sendPacketOut(pktOut, pair.getLeft(), interfaceName, tunnelId);
}
} catch (Exception e) {
- LOG.warn("Failed to get DHCP Reply {}", e);
+ LOG.warn("Failed to get DHCP Reply");
+ LOG.trace("Reason for failure {}", e);
}
}
}
- private void sendPacketOut(byte[] pktOut, BigInteger dpnId, String interfaceName) {
+ private void sendPacketOut(byte[] pktOut, BigInteger dpnId, String interfaceName, BigInteger tunnelId) {
LOG.trace("Sending packet out DpId {}, portId {}, vlanId {}, interfaceName {}", dpnId, interfaceName);
- List<Action> action = getEgressAction(interfaceName);
+ List<Action> 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) {
+ 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("DHCPRELEASE received");
return null;
}
-
- Port nPort = getNeutronPort(interfaceName);
+ 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);
List<IpAddress> dnsServers = nSubnet.getDnsNameservers();
dhcpInfo = new DhcpInfo();
dhcpInfo.setClientIp(clientIp).setServerIp(serverIp)
- .setCidr(nSubnet.getCidr()).setHostRoutes(nSubnet.getHostRoutes())
+ .setCidr(String.valueOf(nSubnet.getCidr().getValue()))
+ .setHostRoutes(nSubnet.getHostRoutes())
.setDnsServersIpAddrs(dnsServers).setGatewayIp(serverIp);
- } else {
- //FIXME: Delete this test code
- LOG.error("TestOnly Code");
- dhcpInfo = new DhcpInfo();
- dhcpInfo.setClientIp("1.1.1.3").setServerIp("1.1.1.1")
- .setCidr("1.1.1.0/24").addDnsServer("1.1.1.1");
- LOG.warn("Failed to get Subnet info for DHCP reply");
}
return dhcpInfo;
}
private DHCP getDhcpPktIn(Ethernet actualEthernetPacket) {
Ethernet ethPkt = actualEthernetPacket;
- LOG.trace("Inside getDhcpPktIn ethPkt {} \n getPayload {}", ethPkt, ethPkt.getPayload());
if (ethPkt.getEtherType() == (short)NwConstants.ETHTYPE_802_1Q) {
ethPkt = (Ethernet)ethPkt.getPayload();
}
try {
reply.deserialize(rawDhcpPayload, 0, rawDhcpPayload.length);
} catch (PacketException e) {
- LOG.warn("Failed to deserialize DHCP pkt {}", e);
+ LOG.warn("Failed to deserialize DHCP pkt");
+ LOG.trace("Reason for failure {}", e);
return null;
}
return reply;
ether.setEtherType(EtherTypes.IPv4.shortValue());
ether.setPayload(ip4Reply);
}
- //TODO:
ether.setSourceMACAddress(getServerMacAddress(phyAddrees));
ether.setDestinationMACAddress(etherPkt.getSourceMACAddress());
return id;
}
- private List<Action> getEgressAction(String interfaceName) {
+ private List<Action> getEgressAction(String interfaceName, BigInteger tunnelId) {
List<Action> actions = null;
try {
+ GetEgressActionsForInterfaceInputBuilder egressAction = new GetEgressActionsForInterfaceInputBuilder().setIntfName(interfaceName);
+ if (tunnelId != null) {
+ egressAction.setTunnelKey(tunnelId.longValue());
+ }
Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
- interfaceManagerRpc.getEgressActionsForInterface(
- new GetEgressActionsForInterfaceInputBuilder().setIntfName(interfaceName).build());
+ interfaceManagerRpc.getEgressActionsForInterface(egressAction.build());
RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
if(!rpcResult.isSuccessful()) {
LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", interfaceName, rpcResult.getErrors());
}
private ImmutablePair<BigInteger, String> getDpnIdPhysicalAddressFromInterfaceName(String interfaceName) {
- ImmutablePair<BigInteger, String> pair = localCache.get(interfaceName);
+ ImmutablePair<BigInteger, String> pair = dhcpMgr.getInterfaceCache(interfaceName);
if (pair!=null && pair.getLeft() != null && pair.getRight() != null) {
return pair;
}
BigInteger dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
String phyAddress = interfaceState==null ? "":interfaceState.getPhysAddress().getValue();
pair = new ImmutablePair<BigInteger, String>(dpId, phyAddress);
- localCache.put(interfaceName, pair);
- return null;
+ dhcpMgr.updateInterfaceCache(interfaceName, pair);
+ return pair;
}
}