2 * Copyright (c) 2016, 2017 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
8 package org.opendaylight.genius.interfacemanager.servicebindings.flowbased.config.helpers;
10 import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.List;
15 import java.util.concurrent.ConcurrentHashMap;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18 import org.apache.aries.blueprint.annotation.service.Reference;
19 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
20 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
21 import org.opendaylight.genius.mdsalutil.MatchInfo;
22 import org.opendaylight.genius.mdsalutil.NwConstants;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
25 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.bound.services.state.list.BoundServicesState;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
31 import org.opendaylight.yangtools.yang.common.Uint64;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 public class FlowBasedIngressServicesConfigUnbindHelper extends AbstractFlowBasedServicesConfigUnbindHelper {
38 private static final Logger LOG = LoggerFactory.getLogger(FlowBasedIngressServicesConfigUnbindHelper.class);
40 private final ManagedNewTransactionRunner txRunner;
41 private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
44 public FlowBasedIngressServicesConfigUnbindHelper(@Reference final DataBroker dataBroker,
45 final InterfaceManagerCommonUtils interfaceManagerCommonUtils) {
46 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
47 this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
51 protected void unbindServiceOnInterface(List<ListenableFuture<?>> futures, BoundServices boundServiceOld,
52 List<BoundServices> boundServices, BoundServicesState boundServicesState) {
53 // Split based on type of interface....
54 if (L2vlan.class.equals(boundServicesState.getInterfaceType())) {
55 unbindServiceOnVlan(futures, boundServiceOld, boundServices, boundServicesState);
56 } else if (Tunnel.class.equals(boundServicesState.getInterfaceType())) {
57 unbindServiceOnTunnel(futures, boundServiceOld, boundServices, boundServicesState);
61 private void unbindServiceOnVlan(List<ListenableFuture<?>> futures, BoundServices boundServiceOld,
62 List<BoundServices> boundServices, BoundServicesState boundServicesState) {
63 LOG.info("unbinding ingress service {} for vlan port: {}", boundServiceOld.getServiceName(),
64 boundServicesState.getInterfaceName());
65 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
66 Uint64 dpId = boundServicesState.getDpid();
67 if (boundServices == null || boundServices.isEmpty()) {
68 // Remove default entry from Lport Dispatcher Table.
69 FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, boundServicesState.getInterfaceName(),
70 boundServiceOld, tx, NwConstants.DEFAULT_SERVICE_INDEX);
73 BoundServices[] highLow =
74 FlowBasedServicesUtils.getHighAndLowPriorityService(boundServices, boundServiceOld);
75 BoundServices low = highLow[0];
76 BoundServices high = highLow[1];
77 // This means the one removed was the highest priority service
79 LOG.trace("Deleting ingress dispatcher table entry for service {}, match service index {}",
80 boundServiceOld, NwConstants.DEFAULT_SERVICE_INDEX);
81 FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, boundServicesState.getInterfaceName(),
82 boundServiceOld, tx, NwConstants.DEFAULT_SERVICE_INDEX);
84 // delete the lower services flow entry.
85 LOG.trace("Deleting ingress dispatcher table entry for lower service {}, match service index {}",
86 low, low.getServicePriority().toJava());
87 FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, boundServicesState.getInterfaceName(), low,
88 tx, low.getServicePriority().toJava());
89 BoundServices lower = FlowBasedServicesUtils.getHighAndLowPriorityService(boundServices, low)[0];
90 short lowerServiceIndex = (short) (lower != null ? lower.getServicePriority().toJava()
91 : low.getServicePriority().toJava() + 1);
92 LOG.trace("Installing new ingress dispatcher table entry for lower service {}, match service index "
93 + "{}, update service index {}",
94 low, NwConstants.DEFAULT_SERVICE_INDEX, lowerServiceIndex);
95 FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, low, boundServicesState.getInterfaceName(),
96 tx, boundServicesState.getIfIndex(), NwConstants.DEFAULT_SERVICE_INDEX, lowerServiceIndex);
99 LOG.trace("Deleting ingress dispatcher table entry for service {}, match service index {}",
100 boundServiceOld, boundServiceOld.getServicePriority());
101 FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, boundServicesState.getInterfaceName(),
102 boundServiceOld, tx, boundServiceOld.getServicePriority().toJava());
103 short lowerServiceIndex = (short) (low != null ? low.getServicePriority().toJava()
104 : boundServiceOld.getServicePriority().toJava() + 1);
105 BoundServices highest = FlowBasedServicesUtils.getHighestPriorityService(boundServices);
106 if (high.equals(highest)) {
107 LOG.trace("Update the existing higher service {}, match service index {}, update service index {}",
108 high, NwConstants.DEFAULT_SERVICE_INDEX, lowerServiceIndex);
109 FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, high, boundServicesState.getInterfaceName(),
110 tx, boundServicesState.getIfIndex(), NwConstants.DEFAULT_SERVICE_INDEX, lowerServiceIndex);
112 LOG.trace("Update the existing higher service {}, match service index {}, update service index {}",
113 high, high.getServicePriority(), lowerServiceIndex);
114 FlowBasedServicesUtils.installLPortDispatcherFlow(dpId, high, boundServicesState.getInterfaceName(),
115 tx, boundServicesState.getIfIndex(), high.getServicePriority().toJava(), lowerServiceIndex);
121 private void unbindServiceOnTunnel(List<ListenableFuture<?>> futures, BoundServices boundServiceOld,
122 List<BoundServices> boundServices, BoundServicesState boundServicesState) {
123 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
124 Uint64 dpId = boundServicesState.getDpid();
126 LOG.info("unbinding ingress service {} for tunnel port: {}", boundServiceOld.getServiceName(),
127 boundServicesState.getInterfaceName());
129 if (boundServices.isEmpty()) {
130 // Remove entry from Ingress Table.
131 FlowBasedServicesUtils.removeIngressFlow(boundServicesState.getInterfaceName(), boundServiceOld, dpId,
136 Map<Short, BoundServices> tmpServicesMap = new ConcurrentHashMap<>();
137 short highestPriority = 0xFF;
138 for (BoundServices boundService : boundServices) {
139 tmpServicesMap.put(boundService.getServicePriority().toJava(), boundService);
140 if (boundService.getServicePriority().toJava() < highestPriority) {
141 highestPriority = boundService.getServicePriority().toJava();
145 if (highestPriority < boundServiceOld.getServicePriority().toJava()) {
146 FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, boundServicesState.getInterfaceName(),
147 boundServiceOld, tx, boundServiceOld.getServicePriority().toJava());
151 List<MatchInfo> matches;
152 long portNo = boundServicesState.getPortNo().toJava();
153 matches = FlowBasedServicesUtils.getMatchInfoForTunnelPortAtIngressTable(dpId, portNo);
155 BoundServices toBeMoved = tmpServicesMap.get(highestPriority);
157 interfaceManagerCommonUtils.getInterfaceFromConfigDS(boundServicesState.getInterfaceName());
158 FlowBasedServicesUtils.removeIngressFlow(iface.getName(), boundServiceOld, dpId, tx);
159 FlowBasedServicesUtils.installInterfaceIngressFlow(dpId, iface, toBeMoved, tx, matches,
160 boundServicesState.getIfIndex(), NwConstants.VLAN_INTERFACE_INGRESS_TABLE);
161 FlowBasedServicesUtils.removeLPortDispatcherFlow(dpId, iface.getName(), toBeMoved, tx,
162 toBeMoved.getServicePriority().toJava());
167 protected void unbindServiceOnInterfaceType(List<ListenableFuture<?>> futures, BoundServices boundServiceNew,
168 List<BoundServices> allServices) {
169 LOG.info("unbindServiceOnInterfaceType Ingress - WIP");