2 * Copyright (c) 2016 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
9 package org.opendaylight.vpnservice.dhcpservice;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.LinkedList;
14 import java.util.List;
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;
53 import com.google.common.base.Optional;
55 public class DhcpServiceUtils {
57 private static final Logger logger = LoggerFactory.getLogger(DhcpServiceUtils.class);
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()) {
66 return interfaceOptional.get();
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();
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) {
79 List<MatchInfo> matches = getDhcpMatch(vmMacAddress);
81 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
82 List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
85 actionsInfos.add(new ActionInfo(ActionType.punt_to_controller,
87 instructions.add(new InstructionInfo(InstructionType.write_actions,
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);
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);
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();
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) {
116 List<MatchInfo> matches = getDhcpMatch(vmMacAddress);
118 List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
119 List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
120 instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
122 actionsInfos.add(new ActionInfo(ActionType.drop_action,
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);
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);
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 }));
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()) {
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) {
169 BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeId);
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());
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()) {
195 return interfaceOptional.get();
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()) {
206 Network network = optionalNetwork.get();
207 String segmentationId = NeutronUtils.getSegmentationIdFromNeutronNetwork(network);
208 return segmentationId;
211 public static String getNodeIdFromDpnId(BigInteger dpnId) {
212 return MDSALUtil.NODE_PREFIX + MDSALUtil.SEPARATOR + dpnId.toString();
215 public static String getTrunkPortMacAddress(String parentRefName,
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);
223 return trunkPort.get().getMacAddress();