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 org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
13 import com.google.common.base.Optional;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
17 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
18 import java.math.BigInteger;
19 import java.util.ArrayList;
20 import java.util.List;
21 import com.google.common.util.concurrent.FutureCallback;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.vpnservice.dhcpservice.api.DHCPMConstants;
24 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
25 import org.opendaylight.vpnservice.mdsalutil.ActionType;
26 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
27 import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
28 import org.opendaylight.vpnservice.mdsalutil.InstructionType;
29 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
30 import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
31 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
32 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
33 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
34 import org.opendaylight.vpnservice.mdsalutil.packet.IPProtocols;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 public class DhcpManager implements AutoCloseable {
42 private static final Logger logger = LoggerFactory.getLogger(DhcpManager.class);
43 private final DataBroker broker;
44 IMdsalApiManager mdsalUtil;
46 private int dhcpOptLeaseTime = 0;
47 private int dhcpOptRenewalTime = 0;
48 private int dhcpOptRebindingTime = 0;
49 private String dhcpOptDefDomainName = "openstacklocal";
51 private static final FutureCallback<Void> DEFAULT_CALLBACK =
52 new FutureCallback<Void>() {
53 public void onSuccess(Void result) {
54 logger.debug("Success in Datastore write operation");
56 public void onFailure(Throwable error) {
57 logger.error("Error in Datastore write operation", error);
62 * @param db - dataBroker reference
64 public DhcpManager(final DataBroker db) {
66 configureLeaseDuration(DHCPMConstants.DEFAULT_LEASE_TIME);
69 public void setMdsalManager(IMdsalApiManager mdsalManager) {
70 this.mdsalUtil = mdsalManager;
74 public void close() throws Exception {
75 logger.info("DHCP Manager Closed");
78 public void installDhcpEntries(BigInteger dpnId) {
79 logger.debug("Installing Default DHCP Flow tp DPN: {}", dpnId);
80 setupDefaultDhcpFlow(dpnId, DHCPMConstants.DHCP_TABLE, NwConstants.ADD_FLOW);
83 private void setupDefaultDhcpFlow(BigInteger dpId, short tableId, int addOrRemove) {
85 List<MatchInfo> matches = new ArrayList<MatchInfo>();
87 matches.add(new MatchInfo(MatchFieldType.eth_type,
88 new long[] { NwConstants.ETHTYPE_IPV4 }));
89 matches.add(new MatchInfo(MatchFieldType.ip_proto,
90 new long[] { IPProtocols.UDP.intValue() }));
91 matches.add(new MatchInfo(MatchFieldType.udp_src,
92 new long[] { DHCPMConstants.dhcpClientPort }));
93 matches.add(new MatchInfo(MatchFieldType.udp_dst,
94 new long[] { DHCPMConstants.dhcpServerPort }));
96 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
97 List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
100 actionsInfos.add(new ActionInfo(ActionType.punt_to_controller,
102 instructions.add(new InstructionInfo(InstructionType.write_actions,
104 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
105 getDefaultDhcpFlowRef(dpId, tableId),DHCPMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
106 DHCPMConstants.COOKIE_DHCP_BASE, matches, instructions);
107 mdsalUtil.installFlow(flowEntity);
110 private String getDefaultDhcpFlowRef(BigInteger dpId, long tableId) {
111 return new StringBuffer().append(DHCPMConstants.FLOWID_PREFIX).append(dpId)
112 .append(NwConstants.FLOWID_SEPARATOR).append(tableId).toString();
115 public int setLeaseDuration(int leaseDuration) {
116 configureLeaseDuration(leaseDuration);
117 return getDhcpLeaseTime();
120 public String setDefaultDomain(String defaultDomain) {
121 this.dhcpOptDefDomainName = defaultDomain;
122 return getDhcpDefDomain();
125 protected int getDhcpLeaseTime() {
126 return this.dhcpOptLeaseTime;
129 protected int getDhcpRenewalTime() {
130 return this.dhcpOptLeaseTime;
133 protected int getDhcpRebindingTime() {
134 return this.dhcpOptLeaseTime;
137 protected String getDhcpDefDomain() {
138 return this.dhcpOptDefDomainName;
141 private void configureLeaseDuration(int leaseTime) {
142 this.dhcpOptLeaseTime = leaseTime;
144 this.dhcpOptRenewalTime = this.dhcpOptLeaseTime/2;
145 this.dhcpOptRebindingTime = (this.dhcpOptLeaseTime*7)/8;
147 this.dhcpOptRenewalTime = -1;
148 this.dhcpOptRebindingTime = -1;
152 public Subnet getNeutronSubnet(Port nPort) {
153 /* TODO: Once NeutronVpn is merged, use it to get Subnet
156 return neutronVpnService.getNeutronSubnet(nPort.getFixedIps().get(0).getSubnetId());
157 } catch (Exception e) {
158 logger.warn("Failed to get Neutron Subnet from Port: {}", e);
162 if (nPort.getFixedIps() != null && !nPort.getFixedIps().isEmpty()) {
163 InstanceIdentifier<Subnet> sIid =
164 InstanceIdentifier.create(Neutron.class).child(Subnets.class)
165 .child(Subnet.class, new SubnetKey(nPort.getFixedIps().get(0).getSubnetId()));
166 Optional<Subnet> optSubnet = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, sIid, broker);
167 if (optSubnet.isPresent()) {
168 return optSubnet.get();
174 public Port getNeutronPort(String name) {
175 // TODO Once NeutronVpn is merged, use it to get port
176 //return neutronVpnService.getNeutronPort(name);
177 InstanceIdentifier<Ports> pIid = InstanceIdentifier.create(Neutron.class).child(Ports.class);
178 Optional<Ports> optPorts = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, pIid, broker);
179 if(optPorts.isPresent()) {
180 for(Port port: optPorts.get().getPort()) {
181 if(port.getUuid().getValue().startsWith(name.substring(3))) {