c6fd549221261fa27daba380815468f7bae552f0
[vpnservice.git] / dhcpservice / dhcpservice-impl / src / main / java / org / opendaylight / vpnservice / dhcpservice / DhcpServiceUtils.java
1 /*
2  * Copyright (c) 2016 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
9 package org.opendaylight.vpnservice.dhcpservice;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.LinkedList;
14 import java.util.List;
15
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.vpnservice.dhcpservice.api.DHCPMConstants;
19 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
20 import org.opendaylight.vpnservice.mdsalutil.ActionType;
21 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
22 import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
23 import org.opendaylight.vpnservice.mdsalutil.InstructionType;
24 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
25 import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
26 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
27 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
28 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
29 import org.opendaylight.vpnservice.mdsalutil.packet.IPProtocols;
30 import org.opendaylight.vpnservice.neutronvpn.api.utils.NeutronUtils;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.ElanDpnInterfaces;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 import com.google.common.base.Optional;
54
55 public class DhcpServiceUtils {
56
57     private static final Logger logger = LoggerFactory.getLogger(DhcpServiceUtils.class);
58
59     public static Interface getInterfaceFromConfigDS(String interfaceName, DataBroker dataBroker) {
60         InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
61         InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(interfaceKey);
62         Optional<Interface> interfaceOptional = MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId, dataBroker);
63         if (!interfaceOptional.isPresent()) {
64             return null;
65         }
66         return interfaceOptional.get();
67     }
68
69     private static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
70         InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder =
71                 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, interfaceKey);
72         return interfaceInstanceIdentifierBuilder.build();
73     }
74
75     public static void setupDhcpFlowEntry(BigInteger dpId, short tableId, String vmMacAddress, int addOrRemove, IMdsalApiManager mdsalUtil) {
76         if (dpId == null || dpId.equals(DHCPMConstants.INVALID_DPID) || vmMacAddress == null) {
77             return;
78         }
79         List<MatchInfo> matches = getDhcpMatch(vmMacAddress);
80
81         List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
82         List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
83
84         // Punt to controller
85         actionsInfos.add(new ActionInfo(ActionType.punt_to_controller,
86                 new String[] {}));
87         instructions.add(new InstructionInfo(InstructionType.write_actions,
88                 actionsInfos));
89         if (addOrRemove == NwConstants.DEL_FLOW) {
90             FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
91                     getDhcpFlowRef(dpId, tableId, vmMacAddress),
92                     DHCPMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
93                     DHCPMConstants.COOKIE_DHCP_BASE, matches, null);
94             logger.trace("Removing DHCP Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
95             mdsalUtil.removeFlow(flowEntity);
96         } else {
97             FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
98                     getDhcpFlowRef(dpId, tableId, vmMacAddress),DHCPMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
99                     DHCPMConstants.COOKIE_DHCP_BASE, matches, instructions);
100             logger.trace("Installing DHCP Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
101             mdsalUtil.installFlow(flowEntity);
102         }
103     }
104
105     private static String getDhcpFlowRef(BigInteger dpId, long tableId, String vmMacAddress) {
106         return new StringBuffer().append(DHCPMConstants.FLOWID_PREFIX)
107                 .append(dpId).append(NwConstants.FLOWID_SEPARATOR)
108                 .append(tableId).append(NwConstants.FLOWID_SEPARATOR)
109                 .append(vmMacAddress).toString();
110     }
111
112     public static void setupDhcpDropAction(BigInteger dpId, short tableId, String vmMacAddress, int addOrRemove, IMdsalApiManager mdsalUtil) {
113         if (dpId == null || dpId.equals(DHCPMConstants.INVALID_DPID) || vmMacAddress == null) {
114             return;
115         }
116         List<MatchInfo> matches = getDhcpMatch(vmMacAddress);
117
118         List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
119         List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
120         instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
121         // Drop Action
122         actionsInfos.add(new ActionInfo(ActionType.drop_action,
123                 new String[] {}));
124         if (addOrRemove == NwConstants.DEL_FLOW) {
125             FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
126                     getDhcpFlowRef(dpId, tableId, vmMacAddress),
127                     DHCPMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
128                     DHCPMConstants.COOKIE_DHCP_BASE, matches, null);
129             logger.trace("Removing DHCP Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
130             mdsalUtil.removeFlow(flowEntity);
131         } else {
132             FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,
133                     getDhcpFlowRef(dpId, tableId, vmMacAddress),DHCPMConstants.DEFAULT_DHCP_FLOW_PRIORITY, "DHCP", 0, 0,
134                     DHCPMConstants.COOKIE_DHCP_BASE, matches, instructions);
135             logger.trace("Installing DHCP Flow DpId {}, vmMacAddress {}", dpId, vmMacAddress);
136             mdsalUtil.installFlow(flowEntity);
137         }
138     }
139
140     private static List<MatchInfo> getDhcpMatch(String vmMacAddress) {
141         List<MatchInfo> matches = new ArrayList<MatchInfo>();
142         matches.add(new MatchInfo(MatchFieldType.eth_type,
143                 new long[] { NwConstants.ETHTYPE_IPV4 }));
144         matches.add(new MatchInfo(MatchFieldType.ip_proto,
145                 new long[] { IPProtocols.UDP.intValue() }));
146         matches.add(new MatchInfo(MatchFieldType.udp_src,
147                 new long[] { DHCPMConstants.dhcpClientPort }));
148         matches.add(new MatchInfo(MatchFieldType.udp_dst,
149                 new long[] { DHCPMConstants.dhcpServerPort }));
150         matches.add(new MatchInfo(MatchFieldType.eth_src,
151                 new String[] { vmMacAddress }));
152         return matches;
153     }
154
155     public static List<BigInteger> getListOfDpns(DataBroker broker) {
156         List<BigInteger> dpnsList = new LinkedList<BigInteger>();
157         InstanceIdentifier<Nodes> nodesInstanceIdentifier = InstanceIdentifier.builder(Nodes.class).build();
158         Optional<Nodes> nodesOptional = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, nodesInstanceIdentifier);
159         if (!nodesOptional.isPresent()) {
160             return dpnsList;
161         }
162         Nodes nodes = nodesOptional.get();
163         List<Node> nodeList = nodes.getNode();
164         for (Node node : nodeList) {
165             NodeId nodeId = node.getId();
166             if (nodeId == null) {
167                 continue;
168             }
169             BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeId);
170             dpnsList.add(dpnId);
171         }
172         return dpnsList;
173     }
174
175     public static List<BigInteger> getDpnsForElan(String elanInstanceName, DataBroker broker) {
176         List<BigInteger> elanDpns = new LinkedList<BigInteger>();
177         InstanceIdentifier<ElanDpnInterfacesList> elanDpnInstanceIdentifier = InstanceIdentifier.builder(ElanDpnInterfaces.class).child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName)).build();
178         Optional<ElanDpnInterfacesList> elanDpnOptional = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, elanDpnInstanceIdentifier);
179         if (elanDpnOptional.isPresent()) {
180             List<DpnInterfaces> dpns = elanDpnOptional.get().getDpnInterfaces();
181             for (DpnInterfaces dpnInterfaces : dpns) {
182                 elanDpns.add(dpnInterfaces.getDpId());
183             }
184         }
185         return elanDpns;
186     }
187
188     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceFromOperationalDS(String interfaceName, DataBroker dataBroker) {
189         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey interfaceKey = new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName);
190         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceId = InstanceIdentifier.builder(InterfacesState.class).child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class, interfaceKey).build();
191         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> interfaceOptional = MDSALUtil.read(LogicalDatastoreType.OPERATIONAL, interfaceId, dataBroker);
192         if (!interfaceOptional.isPresent()) {
193             return null;
194         }
195         return interfaceOptional.get();
196     }
197
198
199     public static String getSegmentationId(Uuid networkId, DataBroker broker) {
200         InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).child(Networks.class).child
201                 (Network.class, new NetworkKey(networkId));
202         Optional<Network> optionalNetwork = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, inst);
203         if (!optionalNetwork.isPresent()) {
204             return null;
205         }
206         Network network = optionalNetwork.get();
207         String segmentationId = NeutronUtils.getSegmentationIdFromNeutronNetwork(network);
208         return segmentationId;
209     }
210
211     public static String getNodeIdFromDpnId(BigInteger dpnId) {
212         return MDSALUtil.NODE_PREFIX + MDSALUtil.SEPARATOR + dpnId.toString();
213     }
214
215     public static String getTrunkPortMacAddress(String parentRefName,
216             DataBroker broker) {
217         InstanceIdentifier<Port> portInstanceIdentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class);
218         Optional<Port> trunkPort = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, portInstanceIdentifier);
219         if (!trunkPort.isPresent()) {
220             logger.warn("Trunk port {} not available for sub-port", parentRefName);
221             return null;
222         }
223         return trunkPort.get().getMacAddress();
224     }
225 }