2 * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp.bvi;
11 import com.google.common.base.Preconditions;
12 import com.google.common.eventbus.Subscribe;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.LoopbackCommand;
15 import org.opendaylight.groupbasedpolicy.renderer.vpp.event.GbpSubnetEvent;
16 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispConfigCommandFailedException;
17 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper;
18 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.GbpSubnet;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 import javax.annotation.Nonnull;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.concurrent.ExecutionException;
35 * Created by Shakib Ahmed on 4/26/17.
37 public class BviManager {
38 private static final Logger LOG = LoggerFactory.getLogger(BviManager.class);
40 private ConfigManagerHelper managerHelper;
42 private HashMap<String, GbpSubnet> subnetInformation;
44 private BviHostSpecificInfo bviHostSpecificInfo;
45 private NeutronTenantToVniMapper neutronTenantToVniMapper;
47 public BviManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) {
48 managerHelper = new ConfigManagerHelper(mountedDataBrokerProvider);
49 subnetInformation = new HashMap<>();
50 bviHostSpecificInfo = new BviHostSpecificInfo();
51 neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance();
55 public synchronized void gbpSubnetChanged(GbpSubnetEvent event) {
56 final GbpSubnet oldGbpSubnet = event.getBefore().orNull();
57 final GbpSubnet newGbpSubnet = event.getAfter().orNull();
58 switch (event.getDtoModificationType()) {
60 Preconditions.checkNotNull(newGbpSubnet);
61 processSubnetCreated(newGbpSubnet.getId(), newGbpSubnet);
64 Preconditions.checkNotNull(oldGbpSubnet);
65 Preconditions.checkNotNull(newGbpSubnet);
66 processSubnetDeleted(oldGbpSubnet.getId());
67 processSubnetCreated(newGbpSubnet.getId(), newGbpSubnet);
70 Preconditions.checkNotNull(oldGbpSubnet);
71 processSubnetDeleted(oldGbpSubnet.getId());
76 private void processSubnetCreated(String subnetUuid, GbpSubnet subnetInfo) {
77 subnetInformation.put(subnetUuid, subnetInfo);
80 private void processSubnetDeleted(String subnetUuid) {
81 subnetInformation.remove(subnetUuid);
83 deleteBviIfExists(subnetUuid);
86 public GbpSubnet getSubnetInfo(String subnetUuid) {
87 return subnetInformation.get(subnetUuid);
90 public void createBviIfNecessary(AddressEndpointWithLocation addressEp,
91 String bridgeDomainName) {
93 DataBroker vppDataBroker = managerHelper.getPotentialExternalDataBroker(addressEp).get();
94 String hostName = managerHelper.getHostName(addressEp).get();
95 String subnetUuid = managerHelper.getSubnet(addressEp);
97 if (bviHostSpecificInfo.bviAlreadyExists(hostName, subnetUuid)) {
101 GbpSubnet gbpSubnetInfo = Preconditions.checkNotNull(getSubnetInfo(subnetUuid),
102 "Subnet UUID {} hasn't been created yet!", subnetUuid);
104 LoopbackCommand.LoopbackCommandBuilder loopbackCommandBuilder =
105 new LoopbackCommand.LoopbackCommandBuilder();
106 loopbackCommandBuilder.setInterfaceName("loop"
107 + bviHostSpecificInfo.getBviCount(hostName));
108 loopbackCommandBuilder.setBridgeDomain(bridgeDomainName);
109 loopbackCommandBuilder.setBvi(true);
110 loopbackCommandBuilder.setEnabled(true);
111 loopbackCommandBuilder.setVrfId(getVni(addressEp.getTenant().getValue()));
112 loopbackCommandBuilder.setIpAddress(gbpSubnetInfo.getGatewayIp());
113 loopbackCommandBuilder.setIpPrefix(gbpSubnetInfo.getCidr());
114 loopbackCommandBuilder.setOperation(General.Operations.PUT);
115 createBviInterface(hostName, vppDataBroker, loopbackCommandBuilder);
116 } catch (LispConfigCommandFailedException e) {
117 LOG.debug("LISP loopback command failed for {}", e.getMessage());
121 public void createBviInterface(String hostName, DataBroker vppDataBroker,
122 LoopbackCommand.LoopbackCommandBuilder commandBuilder) throws LispConfigCommandFailedException {
124 if (GbpNetconfTransaction.netconfSyncedWrite(vppDataBroker,
125 commandBuilder.build(),
126 GbpNetconfTransaction.RETRY_COUNT)) {
127 bviHostSpecificInfo.addBviForHost(hostName,
128 commandBuilder.getBridgeDomain(),
129 commandBuilder.getInterfaceName());
131 throw new LispConfigCommandFailedException("BVI could not be created for "
132 + hostName + " and bridge domain " + commandBuilder.getBridgeDomain());
136 public void deleteBviIfExists(String subnetUuid) {
138 List<String> hostsWithSubnet = bviHostSpecificInfo.getHostsWithSubnet(subnetUuid);
140 hostsWithSubnet.forEach(host -> {
141 DataBroker vppDataBroker = managerHelper.getPotentialExternalDataBroker(host).get();
142 String bviInterfaceName = bviHostSpecificInfo.getInterfaceNameForBviInHost(host, subnetUuid);
143 GbpNetconfTransaction.netconfSyncedDelete(vppDataBroker,
144 VppIidFactory.getInterfaceIID(new InterfaceKey(bviInterfaceName)), GbpNetconfTransaction.RETRY_COUNT);
148 private long getVni(String tenantUuid) {
149 return neutronTenantToVniMapper.getVni(tenantUuid);