2 * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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.netvirt.natservice.internal;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Collection;
15 import java.util.List;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.genius.mdsalutil.ActionInfo;
19 import org.opendaylight.genius.mdsalutil.ActionType;
20 import org.opendaylight.genius.mdsalutil.BucketInfo;
21 import org.opendaylight.genius.mdsalutil.GroupEntity;
22 import org.opendaylight.genius.mdsalutil.MDSALUtil;
23 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
24 import org.opendaylight.netvirt.elanmanager.api.IElanService;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 import com.google.common.base.Strings;
35 public class ExternalNetworkGroupInstaller {
36 private static final Logger LOG = LoggerFactory.getLogger(ExternalNetworkGroupInstaller.class);
37 private static final long FIXED_DELAY_IN_MILLISECONDS = 4000;
39 private final DataBroker broker;
40 private final IMdsalApiManager mdsalManager;
41 private final IElanService elanService;
42 private final IdManagerService idManager;
43 private final OdlInterfaceRpcService interfaceManager;
45 public ExternalNetworkGroupInstaller(final DataBroker broker, final IMdsalApiManager mdsalManager,
46 final IElanService elanService, final IdManagerService idManager,
47 final OdlInterfaceRpcService interfaceManager) {
49 this.mdsalManager = mdsalManager;
50 this.elanService = elanService;
51 this.idManager = idManager;
52 this.interfaceManager = interfaceManager;
55 public void installExtNetGroupEntries(Subnetmap subnetMap) {
56 if (subnetMap == null) {
57 LOG.trace("Subnetmap is null");
61 if (NatUtil.isIPv6Subnet(subnetMap.getSubnetIp())) {
62 LOG.trace("Subnet id {} is not an IPv4 subnet, hence skipping.", subnetMap.getId());
66 Uuid networkId = subnetMap.getNetworkId();
67 Uuid subnetId = subnetMap.getId();
68 if (networkId == null) {
69 LOG.trace("No network associated subnet id {}", subnetId.getValue());
73 String macAddress = NatUtil.getSubnetGwMac(broker, subnetId, networkId.getValue());
74 installExtNetGroupEntries(subnetMap, macAddress);
77 public void installExtNetGroupEntries(Uuid subnetId, String macAddress) {
78 Subnetmap subnetMap = NatUtil.getSubnetMap(broker, subnetId);
79 if (NatUtil.isIPv6Subnet(subnetMap.getSubnetIp())) {
80 LOG.trace("Subnet-id {} is not an IPv4 subnet, hence skipping.", subnetMap.getId());
83 installExtNetGroupEntries(subnetMap, macAddress);
86 public void installExtNetGroupEntries(Uuid networkId, BigInteger dpnId) {
87 if (networkId == null) {
91 List<Uuid> subnetIds = NatUtil.getSubnetIdsFromNetworkId(broker, networkId);
92 if (subnetIds == null || subnetIds.isEmpty()) {
93 LOG.trace("No subnet ids associated network id {}", networkId.getValue());
97 for (Uuid subnetId : subnetIds) {
98 String macAddress = NatUtil.getSubnetGwMac(broker, subnetId, networkId.getValue());
99 installExtNetGroupEntry(networkId, subnetId, dpnId, macAddress);
103 private void installExtNetGroupEntries(Subnetmap subnetMap, String macAddress) {
104 if (subnetMap == null) {
105 LOG.trace("Subnetmap is null");
109 String subnetName = subnetMap.getId().getValue();
110 Uuid networkId = subnetMap.getNetworkId();
111 if (networkId == null) {
112 LOG.trace("No network associated subnet id {}", subnetName);
116 Collection<String> extInterfaces = elanService.getExternalElanInterfaces(networkId.getValue());
117 if (extInterfaces == null || extInterfaces.isEmpty()) {
118 LOG.trace("No external ELAN interfaces attached to subnet {}", subnetName);
122 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(subnetName), idManager);
124 LOG.info("Installing ext-net group {} entry for subnet {} with macAddress {} (extInterfaces: {})",
125 groupId, subnetName, macAddress, Arrays.toString(extInterfaces.toArray()));
126 for (String extInterface : extInterfaces) {
127 installExtNetGroupEntry(groupId, subnetName, extInterface, macAddress);
131 private void installExtNetGroupEntry(Uuid networkId, Uuid subnetId, BigInteger dpnId, String macAddress) {
132 String subnetName = subnetId.getValue();
133 String extInterface = elanService.getExternalElanInterface(networkId.getValue(), dpnId);
134 if (extInterface == null) {
135 LOG.trace("No external ELAN interface attached to subnet {} DPN id {}", subnetName, dpnId);
139 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(subnetName), idManager);
140 LOG.info("Installing ext-net group {} entry for subnet {} with macAddress {} (extInterface: {})", groupId,
141 subnetName, macAddress, extInterface);
142 installExtNetGroupEntry(groupId, subnetName, extInterface, macAddress);
145 private void installExtNetGroupEntry(long groupId, String subnetName, String extInterface, String macAddress) {
146 GroupEntity groupEntity = buildExtNetGroupEntity(macAddress, subnetName, groupId, extInterface);
147 if (groupEntity != null) {
148 mdsalManager.syncInstallGroup(groupEntity, FIXED_DELAY_IN_MILLISECONDS);
152 public void removeExtNetGroupEntries(Subnetmap subnetMap) {
153 if (subnetMap == null) {
157 String subnetName = subnetMap.getId().getValue();
158 Uuid networkId = subnetMap.getNetworkId();
159 if (networkId == null) {
160 LOG.warn("No external network associated subnet id {}", subnetName);
164 Collection<String> extInterfaces = elanService.getExternalElanInterfaces(networkId.getValue());
165 if (extInterfaces == null || extInterfaces.isEmpty()) {
166 LOG.trace("No external ELAN interfaces attached to subnet {}", subnetName);
170 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(subnetName), idManager);
172 for (String extInterface : extInterfaces) {
173 GroupEntity groupEntity = buildEmptyExtNetGroupEntity(subnetName, groupId, extInterface);
174 if (groupEntity != null) {
175 LOG.trace("Remove ext-net Group: id {}, subnet id {}", groupId, subnetName);
176 NatServiceCounters.remove_external_network_group.inc();
177 mdsalManager.syncRemoveGroup(groupEntity);
182 private GroupEntity buildExtNetGroupEntity(String macAddress, String subnetName, long groupId, String extInterface) {
183 BigInteger dpId = NatUtil.getDpnForInterface(interfaceManager, extInterface);
184 if (BigInteger.ZERO.equals(dpId)) {
185 LOG.warn("No DPN for interface {}. NAT ext-net flow will not be installed", extInterface);
189 List<ActionInfo> actionList = new ArrayList<>();
190 final int setFieldEthDestActionPos = 0;
191 List<ActionInfo> egressActionList = NatUtil.getEgressActionsForInterface(interfaceManager, extInterface, null,
192 setFieldEthDestActionPos + 1);
194 if (Strings.isNullOrEmpty(macAddress) || egressActionList == null || egressActionList.isEmpty()) {
195 if (Strings.isNullOrEmpty(macAddress)) {
196 LOG.trace("Building ext-net group {} entry with drop action since "
197 + "GW mac has not been resolved for subnet {} extInterface {}",
198 groupId, subnetName, extInterface);
200 LOG.warn("Building ext-net group {} entry with drop action since "
201 + "no egress actions were found for subnet {} extInterface {}",
202 groupId, subnetName, extInterface);
204 actionList.add(new ActionInfo(ActionType.drop_action, new String[] {}));
206 LOG.trace("Building ext-net group {} entry for subnet {} extInterface {} macAddress {}",
207 groupId, subnetName, extInterface, macAddress);
208 actionList.add(new ActionInfo(ActionType.set_field_eth_dest, new String[] { macAddress }, setFieldEthDestActionPos));
209 actionList.addAll(egressActionList);
212 List<BucketInfo> listBucketInfo = new ArrayList<>();
213 listBucketInfo.add(new BucketInfo(actionList));
214 return MDSALUtil.buildGroupEntity(dpId, groupId, subnetName, GroupTypes.GroupAll, listBucketInfo);
217 private GroupEntity buildEmptyExtNetGroupEntity(String subnetName, long groupId, String extInterface) {
218 BigInteger dpId = NatUtil.getDpnForInterface(interfaceManager, extInterface);
219 if (BigInteger.ZERO.equals(dpId)) {
220 LOG.warn("No DPN for interface {}. NAT ext-net flow will not be installed", extInterface);
224 return MDSALUtil.buildGroupEntity(dpId, groupId, subnetName, GroupTypes.GroupAll, new ArrayList<BucketInfo>());