2 * Copyright (c) 2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package io.fd.honeycomb.v3po.translate.v3po.interfaces;
19 import com.google.common.base.Optional;
20 import io.fd.honeycomb.v3po.translate.v3po.util.AbstractInterfaceTypeCustomizer;
21 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
22 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
23 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
24 import io.fd.honeycomb.v3po.translate.write.WriteContext;
25 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
26 import java.util.concurrent.CompletionStage;
27 import javax.annotation.Nonnull;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Tap;
33 import org.opendaylight.yangtools.yang.binding.DataObject;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.openvpp.jvpp.dto.TapConnect;
36 import org.openvpp.jvpp.dto.TapConnectReply;
37 import org.openvpp.jvpp.dto.TapDelete;
38 import org.openvpp.jvpp.dto.TapDeleteReply;
39 import org.openvpp.jvpp.dto.TapModify;
40 import org.openvpp.jvpp.dto.TapModifyReply;
41 import org.openvpp.jvpp.future.FutureJVpp;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
45 public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
47 private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class);
48 private final NamingContext interfaceContext;
50 public TapCustomizer(final FutureJVpp vppApi, final NamingContext interfaceContext) {
52 this.interfaceContext = interfaceContext;
57 public Optional<Tap> extract(@Nonnull final InstanceIdentifier<Tap> currentId,
58 @Nonnull final DataObject parentData) {
59 return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getTap());
63 protected Class<? extends InterfaceType> getExpectedInterfaceType() {
64 return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class;
68 protected final void writeInterface(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataAfter,
69 @Nonnull final WriteContext writeContext)
70 throws WriteFailedException.CreateFailedException {
72 createTap(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
73 } catch (VppApiInvocationException e) {
74 LOG.warn("Write of Tap failed", e);
75 throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
80 public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataBefore,
81 @Nonnull final Tap dataAfter, @Nonnull final WriteContext writeContext)
82 throws WriteFailedException.UpdateFailedException {
83 final String ifcName = id.firstKeyOf(Interface.class).getName();
87 index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
88 } catch (IllegalArgumentException e) {
89 throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
93 modifyTap(ifcName, index, dataAfter);
94 } catch (VppApiInvocationException e) {
95 LOG.warn("Write of Tap failed", e);
96 throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
101 public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataBefore,
102 @Nonnull final WriteContext writeContext)
103 throws WriteFailedException.DeleteFailedException {
104 final String ifcName = id.firstKeyOf(Interface.class).getName();
108 index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
109 } catch (IllegalArgumentException e) {
110 throw new WriteFailedException.DeleteFailedException(id, e);
114 deleteTap(ifcName, index, dataBefore, writeContext);
115 } catch (VppApiInvocationException e) {
116 LOG.warn("Delete of Tap failed", e);
117 throw new WriteFailedException.DeleteFailedException(id, e);
121 private void createTap(final String swIfName, final Tap tap, final WriteContext writeContext) throws VppApiInvocationException {
122 LOG.debug("Setting tap interface: {}. Tap: {}", swIfName, tap);
123 final CompletionStage<TapConnectReply> tapConnectFuture =
124 getFutureJVpp().tapConnect(getTapConnectRequest(tap.getTapName(), tap.getMac(), tap.getDeviceInstance()));
125 final TapConnectReply reply =
126 V3poUtils.getReply(tapConnectFuture.toCompletableFuture());
127 if (reply.retval < 0) {
128 LOG.warn("Failed to set tap interface: {}, tap: {}", swIfName, tap);
129 throw new VppApiInvocationException("tap_connect", reply.context, reply.retval);
131 LOG.debug("Tap set successfully for: {}, tap: {}", swIfName, tap);
132 // Add new interface to our interface context
133 interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext());
137 private void modifyTap(final String swIfName, final int index, final Tap tap) throws VppApiInvocationException {
138 LOG.debug("Modifying tap interface: {}. Tap: {}", swIfName, tap);
139 final CompletionStage<TapModifyReply> vxlanAddDelTunnelReplyCompletionStage =
140 getFutureJVpp().tapModify(getTapModifyRequest(tap.getTapName(), index, tap.getMac(), tap.getDeviceInstance()));
141 final TapModifyReply reply =
142 V3poUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture());
143 if (reply.retval < 0) {
144 LOG.warn("Failed to modify tap interface: {}, tap: {}", swIfName, tap);
145 throw new VppApiInvocationException("tap_modify", reply.context, reply.retval);
147 LOG.debug("Tap modified successfully for: {}, tap: {}", swIfName, tap);
151 private void deleteTap(final String swIfName, final int index, final Tap dataBefore,
152 final WriteContext writeContext)
153 throws VppApiInvocationException {
154 LOG.debug("Deleting tap interface: {}. Tap: {}", swIfName, dataBefore);
155 final CompletionStage<TapDeleteReply> vxlanAddDelTunnelReplyCompletionStage =
156 getFutureJVpp().tapDelete(getTapDeleteRequest(index));
157 final TapDeleteReply reply =
158 V3poUtils.getReply(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture());
159 if (reply.retval < 0) {
160 LOG.warn("Failed to delete tap interface: {}, tap: {}", swIfName, dataBefore);
161 throw new VppApiInvocationException("tap_modify", reply.context, reply.retval);
163 LOG.debug("Tap deleted successfully for: {}, tap: {}", swIfName, dataBefore);
164 // Remove deleted interface from interface context
165 interfaceContext.removeName(swIfName, writeContext.getMappingContext());
169 private TapConnect getTapConnectRequest(final String tapName, final PhysAddress mac, final Long deviceInstance) {
170 final TapConnect tapConnect = new TapConnect();
171 tapConnect.tapName = tapName.getBytes();
174 tapConnect.useRandomMac = 1;
175 tapConnect.macAddress = new byte[6];
177 tapConnect.useRandomMac = 0;
178 tapConnect.macAddress = V3poUtils.parseMac(mac.getValue());
181 if(deviceInstance == null) {
182 tapConnect.renumber = 0;
184 tapConnect.renumber = 1;
185 tapConnect.customDevInstance = Math.toIntExact(deviceInstance);
191 private TapModify getTapModifyRequest(final String tapName, final int swIndex, final PhysAddress mac, final Long deviceInstance) {
192 final TapModify tapConnect = new TapModify();
193 tapConnect.tapName = tapName.getBytes();
194 tapConnect.swIfIndex = swIndex;
197 tapConnect.useRandomMac = 1;
198 tapConnect.macAddress = new byte[6];
200 tapConnect.useRandomMac = 0;
201 tapConnect.macAddress = V3poUtils.parseMac(mac.getValue());
204 if(deviceInstance == null) {
205 tapConnect.renumber = 0;
207 tapConnect.renumber = 1;
208 tapConnect.customDevInstance = Math.toIntExact(deviceInstance);
214 private TapDelete getTapDeleteRequest(final int swIndex) {
215 final TapDelete tapConnect = new TapDelete();
216 tapConnect.swIfIndex = swIndex;