X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=dhcpservice%2Fdhcpservice-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2Fdhcpservice%2FDhcpManager.java;fp=dhcpservice%2Fdhcpservice-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fvpnservice%2Fdhcpservice%2FDhcpManager.java;h=458ad968210da082b0d554468a3e3b7878dd983e;hb=2dace9ee1047a897bc6c0f3d1a8b05301797bc99;hp=0000000000000000000000000000000000000000;hpb=0f032724da670d7ce19884bd41f7f839f71ad914;p=vpnservice.git diff --git a/dhcpservice/dhcpservice-impl/src/main/java/org/opendaylight/vpnservice/dhcpservice/DhcpManager.java b/dhcpservice/dhcpservice-impl/src/main/java/org/opendaylight/vpnservice/dhcpservice/DhcpManager.java new file mode 100644 index 00000000..458ad968 --- /dev/null +++ b/dhcpservice/dhcpservice-impl/src/main/java/org/opendaylight/vpnservice/dhcpservice/DhcpManager.java @@ -0,0 +1,189 @@ +/* + * 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 org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets; +import com.google.common.base.Optional; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import com.google.common.util.concurrent.FutureCallback; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.vpnservice.dhcpservice.api.DHCPMConstants; +import org.opendaylight.vpnservice.mdsalutil.ActionInfo; +import org.opendaylight.vpnservice.mdsalutil.ActionType; +import org.opendaylight.vpnservice.mdsalutil.FlowEntity; +import org.opendaylight.vpnservice.mdsalutil.InstructionInfo; +import org.opendaylight.vpnservice.mdsalutil.InstructionType; +import org.opendaylight.vpnservice.mdsalutil.MDSALUtil; +import org.opendaylight.vpnservice.mdsalutil.MatchFieldType; +import org.opendaylight.vpnservice.mdsalutil.MatchInfo; +import org.opendaylight.vpnservice.mdsalutil.NwConstants; +import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager; +import org.opendaylight.vpnservice.mdsalutil.packet.IPProtocols; +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.subnets.attributes.subnets.Subnet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DhcpManager implements AutoCloseable { + + private static final Logger logger = LoggerFactory.getLogger(DhcpManager.class); + private final DataBroker broker; + IMdsalApiManager mdsalUtil; + + private int dhcpOptLeaseTime = 0; + private int dhcpOptRenewalTime = 0; + private int dhcpOptRebindingTime = 0; + private String dhcpOptDefDomainName = "openstacklocal"; + + private static final FutureCallback DEFAULT_CALLBACK = + new FutureCallback() { + public void onSuccess(Void result) { + logger.debug("Success in Datastore write operation"); + } + public void onFailure(Throwable error) { + logger.error("Error in Datastore write operation", error); + }; + }; + + /** + * @param db - dataBroker reference + */ + public DhcpManager(final DataBroker db) { + broker = db; + configureLeaseDuration(DHCPMConstants.DEFAULT_LEASE_TIME); + } + + public void setMdsalManager(IMdsalApiManager mdsalManager) { + this.mdsalUtil = mdsalManager; + } + + @Override + public void close() throws Exception { + logger.info("DHCP Manager Closed"); + } + + public void installDhcpEntries(BigInteger dpnId) { + logger.debug("Installing Default DHCP Flow tp DPN: {}", dpnId); + setupDefaultDhcpFlow(dpnId, DHCPMConstants.DHCP_TABLE, NwConstants.ADD_FLOW); + } + + private void setupDefaultDhcpFlow(BigInteger dpId, short tableId, int addOrRemove) { + + List matches = new ArrayList(); + + matches.add(new MatchInfo(MatchFieldType.eth_type, + new long[] { NwConstants.ETHTYPE_IPV4 })); + matches.add(new MatchInfo(MatchFieldType.ip_proto, + new long[] { IPProtocols.UDP.intValue() })); + matches.add(new MatchInfo(MatchFieldType.udp_src, + new long[] { DHCPMConstants.dhcpClientPort })); + matches.add(new MatchInfo(MatchFieldType.udp_dst, + new long[] { DHCPMConstants.dhcpServerPort })); + + List instructions = new ArrayList(); + List actionsInfos = new ArrayList(); + + // Punt to controller + actionsInfos.add(new ActionInfo(ActionType.punt_to_controller, + new String[] {})); + instructions.add(new InstructionInfo(InstructionType.write_actions, + actionsInfos)); + FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, + getDefaultDhcpFlowRef(dpId, tableId),DHCPMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0, + DHCPMConstants.COOKIE_DHCP_BASE, matches, instructions); + mdsalUtil.installFlow(flowEntity); + } + + private String getDefaultDhcpFlowRef(BigInteger dpId, long tableId) { + return new StringBuffer().append(DHCPMConstants.FLOWID_PREFIX).append(dpId) + .append(NwConstants.FLOWID_SEPARATOR).append(tableId).toString(); + } + + public int setLeaseDuration(int leaseDuration) { + configureLeaseDuration(leaseDuration); + return getDhcpLeaseTime(); + } + + public String setDefaultDomain(String defaultDomain) { + this.dhcpOptDefDomainName = defaultDomain; + return getDhcpDefDomain(); + } + + protected int getDhcpLeaseTime() { + return this.dhcpOptLeaseTime; + } + + protected int getDhcpRenewalTime() { + return this.dhcpOptLeaseTime; + } + + protected int getDhcpRebindingTime() { + return this.dhcpOptLeaseTime; + } + + protected String getDhcpDefDomain() { + return this.dhcpOptDefDomainName; + } + + private void configureLeaseDuration(int leaseTime) { + this.dhcpOptLeaseTime = leaseTime; + if(leaseTime > 0) { + this.dhcpOptRenewalTime = this.dhcpOptLeaseTime/2; + this.dhcpOptRebindingTime = (this.dhcpOptLeaseTime*7)/8; + } else { + this.dhcpOptRenewalTime = -1; + this.dhcpOptRebindingTime = -1; + } + } + + public Subnet getNeutronSubnet(Port nPort) { + /* TODO: Once NeutronVpn is merged, use it to get Subnet + if (nPort != null) { + try { + return neutronVpnService.getNeutronSubnet(nPort.getFixedIps().get(0).getSubnetId()); + } catch (Exception e) { + logger.warn("Failed to get Neutron Subnet from Port: {}", e); + } + } + */ + if (nPort.getFixedIps() != null && !nPort.getFixedIps().isEmpty()) { + InstanceIdentifier sIid = + InstanceIdentifier.create(Neutron.class).child(Subnets.class) + .child(Subnet.class, new SubnetKey(nPort.getFixedIps().get(0).getSubnetId())); + Optional optSubnet = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, sIid, broker); + if (optSubnet.isPresent()) { + return optSubnet.get(); + } + } + return null; + } + + public Port getNeutronPort(String name) { + // TODO Once NeutronVpn is merged, use it to get port + //return neutronVpnService.getNeutronPort(name); + InstanceIdentifier pIid = InstanceIdentifier.create(Neutron.class).child(Ports.class); + Optional optPorts = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, pIid, broker); + if(optPorts.isPresent()) { + for(Port port: optPorts.get().getPort()) { + if(port.getUuid().getValue().startsWith(name.substring(3))) { + return port; + } + } + } + return null; + } + +}