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.vpnservice.neutronvpn.interfaces.INeutronVpnManager;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
14 import com.google.common.base.Optional;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
18 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
19 import java.math.BigInteger;
20 import java.util.ArrayList;
21 import java.util.List;
22 import com.google.common.util.concurrent.FutureCallback;
23 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
24 import org.opendaylight.vpnservice.dhcpservice.api.DHCPMConstants;
25 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
26 import org.opendaylight.vpnservice.mdsalutil.ActionType;
27 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
28 import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
29 import org.opendaylight.vpnservice.mdsalutil.InstructionType;
30 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
31 import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
32 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
33 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
34 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
35 import org.opendaylight.vpnservice.mdsalutil.packet.IPProtocols;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 public class DhcpManager implements AutoCloseable {
43 private static final Logger logger = LoggerFactory.getLogger(DhcpManager.class);
44 private final DataBroker broker;
45 IMdsalApiManager mdsalUtil;
47 private int dhcpOptLeaseTime = 0;
48 private int dhcpOptRenewalTime = 0;
49 private int dhcpOptRebindingTime = 0;
50 private String dhcpOptDefDomainName;
51 private INeutronVpnManager neutronVpnService;
53 private static final FutureCallback<Void> DEFAULT_CALLBACK =
54 new FutureCallback<Void>() {
55 public void onSuccess(Void result) {
56 logger.debug("Success in Datastore write operation");
58 public void onFailure(Throwable error) {
59 logger.error("Error in Datastore write operation", error);
64 * @param db - dataBroker reference
66 public DhcpManager(final DataBroker db) {
68 configureLeaseDuration(DHCPMConstants.DEFAULT_LEASE_TIME);
71 public void setMdsalManager(IMdsalApiManager mdsalManager) {
72 this.mdsalUtil = mdsalManager;
75 public void setNeutronVpnService(INeutronVpnManager neutronVpnService) {
76 logger.debug("Setting NeutronVpn dependency");
77 this.neutronVpnService = neutronVpnService;
81 public void close() throws Exception {
82 logger.info("DHCP Manager Closed");
85 public void installDhcpEntries(BigInteger dpnId) {
86 logger.debug("Installing Default DHCP Flow tp DPN: {}", dpnId);
87 setupDefaultDhcpFlow(dpnId, DHCPMConstants.DHCP_TABLE, NwConstants.ADD_FLOW);
90 private void setupDefaultDhcpFlow(BigInteger dpId, short tableId, int addOrRemove) {
92 List<MatchInfo> matches = new ArrayList<MatchInfo>();
94 matches.add(new MatchInfo(MatchFieldType.eth_type,
95 new long[] { NwConstants.ETHTYPE_IPV4 }));
96 matches.add(new MatchInfo(MatchFieldType.ip_proto,
97 new long[] { IPProtocols.UDP.intValue() }));
98 matches.add(new MatchInfo(MatchFieldType.udp_src,
99 new long[] { DHCPMConstants.dhcpClientPort }));
100 matches.add(new MatchInfo(MatchFieldType.udp_dst,
101 new long[] { DHCPMConstants.dhcpServerPort }));
103 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
104 List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
106 // Punt to controller
107 actionsInfos.add(new ActionInfo(ActionType.punt_to_controller,
109 instructions.add(new InstructionInfo(InstructionType.write_actions,
111 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
112 getDefaultDhcpFlowRef(dpId, tableId),DHCPMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
113 DHCPMConstants.COOKIE_DHCP_BASE, matches, instructions);
114 mdsalUtil.installFlow(flowEntity);
117 private String getDefaultDhcpFlowRef(BigInteger dpId, long tableId) {
118 return new StringBuffer().append(DHCPMConstants.FLOWID_PREFIX).append(dpId)
119 .append(NwConstants.FLOWID_SEPARATOR).append(tableId).toString();
122 public int setLeaseDuration(int leaseDuration) {
123 configureLeaseDuration(leaseDuration);
124 return getDhcpLeaseTime();
127 public String setDefaultDomain(String defaultDomain) {
128 this.dhcpOptDefDomainName = defaultDomain;
129 return getDhcpDefDomain();
132 protected int getDhcpLeaseTime() {
133 return this.dhcpOptLeaseTime;
136 protected int getDhcpRenewalTime() {
137 return this.dhcpOptLeaseTime;
140 protected int getDhcpRebindingTime() {
141 return this.dhcpOptLeaseTime;
144 protected String getDhcpDefDomain() {
145 return this.dhcpOptDefDomainName;
148 private void configureLeaseDuration(int leaseTime) {
149 this.dhcpOptLeaseTime = leaseTime;
151 this.dhcpOptRenewalTime = this.dhcpOptLeaseTime/2;
152 this.dhcpOptRebindingTime = (this.dhcpOptLeaseTime*7)/8;
154 this.dhcpOptRenewalTime = -1;
155 this.dhcpOptRebindingTime = -1;
159 public Subnet getNeutronSubnet(Port nPort) {
162 return neutronVpnService.getNeutronSubnet(nPort.getFixedIps().get(0).getSubnetId());
163 } catch (Exception e) {
164 logger.warn("Failed to get Neutron Subnet from Port: {}", e);
170 public Port getNeutronPort(String name) {
171 return neutronVpnService.getNeutronPort(name);