Misc changes to use neutronvpn for dhcpservice
[vpnservice.git] / dhcpservice / dhcpservice-impl / src / main / java / org / opendaylight / vpnservice / dhcpservice / DhcpManager.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.vpnservice.dhcpservice;
9
10 import org.opendaylight.vpnservice.neutronvpn.interfaces.INeutronVpnManager;
11
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;
40
41 public class DhcpManager implements AutoCloseable {
42
43     private static final Logger logger = LoggerFactory.getLogger(DhcpManager.class);
44     private final DataBroker broker;
45     IMdsalApiManager mdsalUtil;
46
47     private int dhcpOptLeaseTime = 0;
48     private int dhcpOptRenewalTime = 0;
49     private int dhcpOptRebindingTime = 0;
50     private String dhcpOptDefDomainName;
51     private INeutronVpnManager neutronVpnService;
52
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");
57             }
58             public void onFailure(Throwable error) {
59                 logger.error("Error in Datastore write operation", error);
60             };
61         };
62
63     /**
64     * @param db - dataBroker reference
65     */
66     public DhcpManager(final DataBroker db) {
67         broker = db;
68         configureLeaseDuration(DHCPMConstants.DEFAULT_LEASE_TIME);
69     }
70
71     public void setMdsalManager(IMdsalApiManager mdsalManager) {
72         this.mdsalUtil = mdsalManager;
73     }
74
75     public void setNeutronVpnService(INeutronVpnManager neutronVpnService) {
76         logger.debug("Setting NeutronVpn dependency");
77         this.neutronVpnService = neutronVpnService;
78     }
79
80     @Override
81     public void close() throws Exception {
82         logger.info("DHCP Manager Closed");
83     }
84
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);
88     }
89
90     private void setupDefaultDhcpFlow(BigInteger dpId,  short tableId, int addOrRemove) {
91
92         List<MatchInfo> matches = new ArrayList<MatchInfo>();
93
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 }));
102
103         List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
104         List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
105
106         // Punt to controller
107         actionsInfos.add(new ActionInfo(ActionType.punt_to_controller,
108                 new String[] {}));
109         instructions.add(new InstructionInfo(InstructionType.write_actions,
110                 actionsInfos));
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);
115     }
116
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();
120     }
121
122     public int setLeaseDuration(int leaseDuration) {
123         configureLeaseDuration(leaseDuration);
124         return getDhcpLeaseTime();
125     }
126
127     public String setDefaultDomain(String defaultDomain) {
128         this.dhcpOptDefDomainName = defaultDomain;
129         return getDhcpDefDomain();
130     }
131
132     protected int getDhcpLeaseTime() {
133         return this.dhcpOptLeaseTime;
134     }
135
136     protected int getDhcpRenewalTime() {
137         return this.dhcpOptLeaseTime;
138     }
139
140     protected int getDhcpRebindingTime() {
141         return this.dhcpOptLeaseTime;
142     }
143
144     protected String getDhcpDefDomain() {
145         return this.dhcpOptDefDomainName;
146     }
147
148     private void configureLeaseDuration(int leaseTime) {
149         this.dhcpOptLeaseTime = leaseTime;
150         if(leaseTime > 0) {
151             this.dhcpOptRenewalTime = this.dhcpOptLeaseTime/2;
152             this.dhcpOptRebindingTime = (this.dhcpOptLeaseTime*7)/8;
153         } else {
154             this.dhcpOptRenewalTime = -1;
155             this.dhcpOptRebindingTime = -1;
156         }
157     }
158
159     public Subnet getNeutronSubnet(Port nPort) {
160         if (nPort != null) {
161             try {
162                 return neutronVpnService.getNeutronSubnet(nPort.getFixedIps().get(0).getSubnetId());
163             } catch (Exception e) {
164                 logger.warn("Failed to get Neutron Subnet from Port: {}", e);
165             }
166         }
167         return null;
168     }
169
170     public Port getNeutronPort(String name) {
171         return neutronVpnService.getNeutronPort(name);
172     }
173
174 }