VPP-378: update jvpp package names
[honeycomb.git] / v3po / v3po2vpp / src / main / java / io / fd / honeycomb / translate / v3po / interfaces / TapCustomizer.java
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
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:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package io.fd.honeycomb.translate.v3po.interfaces;
18
19 import io.fd.honeycomb.translate.vpp.util.AbstractInterfaceTypeCustomizer;
20 import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer;
21 import io.fd.honeycomb.translate.vpp.util.MacTranslator;
22 import io.fd.honeycomb.translate.vpp.util.NamingContext;
23 import io.fd.honeycomb.translate.vpp.util.WriteTimeoutException;
24 import io.fd.honeycomb.translate.write.WriteContext;
25 import io.fd.honeycomb.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.interfaces._interface.Tap;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import io.fd.vpp.jvpp.VppBaseCallException;
34 import io.fd.vpp.jvpp.core.dto.TapConnect;
35 import io.fd.vpp.jvpp.core.dto.TapConnectReply;
36 import io.fd.vpp.jvpp.core.dto.TapDelete;
37 import io.fd.vpp.jvpp.core.dto.TapDeleteReply;
38 import io.fd.vpp.jvpp.core.dto.TapModify;
39 import io.fd.vpp.jvpp.core.dto.TapModifyReply;
40 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> implements MacTranslator, JvppReplyConsumer {
45
46     private static final Logger LOG = LoggerFactory.getLogger(TapCustomizer.class);
47     private final NamingContext interfaceContext;
48
49     public TapCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) {
50         super(vppApi);
51         this.interfaceContext = interfaceContext;
52     }
53
54     @Override
55     protected Class<? extends InterfaceType> getExpectedInterfaceType() {
56         return org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class;
57     }
58
59     @Override
60     protected final void writeInterface(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataAfter,
61                                         @Nonnull final WriteContext writeContext)
62             throws WriteFailedException {
63         final String ifcName = id.firstKeyOf(Interface.class).getName();
64         try {
65             createTap(id, ifcName, dataAfter, writeContext);
66         } catch (VppBaseCallException e) {
67             LOG.warn("Failed to set tap interface: {}, tap: {}", ifcName, dataAfter, e);
68             throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
69         }
70     }
71
72     @Override
73     public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataBefore,
74                                         @Nonnull final Tap dataAfter, @Nonnull final WriteContext writeContext)
75             throws WriteFailedException {
76         final String ifcName = id.firstKeyOf(Interface.class).getName();
77
78         final int index;
79         try {
80             index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
81         } catch (IllegalArgumentException e) {
82             throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
83         }
84
85         try {
86             modifyTap(id, ifcName, index, dataAfter);
87         } catch (VppBaseCallException e) {
88             LOG.warn("Failed to set tap interface: {}, tap: {}", ifcName, dataAfter, e);
89             throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
90         }
91     }
92
93     @Override
94     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id, @Nonnull final Tap dataBefore,
95                                         @Nonnull final WriteContext writeContext)
96             throws WriteFailedException {
97         final String ifcName = id.firstKeyOf(Interface.class).getName();
98
99         final int index;
100         try {
101             index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
102         } catch (IllegalArgumentException e) {
103             throw new WriteFailedException.DeleteFailedException(id, e);
104         }
105
106         try {
107             deleteTap(id, ifcName, index, dataBefore, writeContext);
108         } catch (VppBaseCallException e) {
109             LOG.warn("Failed to delete tap interface: {}, tap: {}", ifcName, dataBefore.getTapName(), e);
110             throw new WriteFailedException.DeleteFailedException(id, e);
111         }
112     }
113
114     private void createTap(final InstanceIdentifier<Tap> id, final String swIfName, final Tap tap,
115                            final WriteContext writeContext) throws VppBaseCallException, WriteTimeoutException {
116         LOG.debug("Setting tap interface: {}. Tap: {}", swIfName, tap);
117         final CompletionStage<TapConnectReply> tapConnectFuture =
118                 getFutureJVpp()
119                         .tapConnect(getTapConnectRequest(tap.getTapName(), tap.getMac(), tap.getDeviceInstance()));
120         final TapConnectReply reply =
121                 getReplyForWrite(tapConnectFuture.toCompletableFuture(), id);
122         LOG.debug("Tap set successfully for: {}, tap: {}", swIfName, tap);
123         // Add new interface to our interface context
124         interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext());
125     }
126
127     private void modifyTap(final InstanceIdentifier<Tap> id, final String swIfName, final int index, final Tap tap)
128             throws VppBaseCallException, WriteTimeoutException {
129         LOG.debug("Modifying tap interface: {}. Tap: {}", swIfName, tap);
130         final CompletionStage<TapModifyReply> vxlanAddDelTunnelReplyCompletionStage =
131                 getFutureJVpp()
132                         .tapModify(getTapModifyRequest(tap.getTapName(), index, tap.getMac(), tap.getDeviceInstance()));
133         getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id);
134         LOG.debug("Tap modified successfully for: {}, tap: {}", swIfName, tap);
135     }
136
137     private void deleteTap(final InstanceIdentifier<Tap> id, final String swIfName, final int index,
138                            final Tap dataBefore,
139                            final WriteContext writeContext)
140             throws VppBaseCallException, WriteTimeoutException {
141         LOG.debug("Deleting tap interface: {}. Tap: {}", swIfName, dataBefore);
142         final CompletionStage<TapDeleteReply> vxlanAddDelTunnelReplyCompletionStage =
143                 getFutureJVpp().tapDelete(getTapDeleteRequest(index));
144         getReplyForWrite(vxlanAddDelTunnelReplyCompletionStage.toCompletableFuture(), id);
145         LOG.debug("Tap deleted successfully for: {}, tap: {}", swIfName, dataBefore);
146         // Remove deleted interface from interface context
147         interfaceContext.removeName(swIfName, writeContext.getMappingContext());
148     }
149
150     private TapConnect getTapConnectRequest(final String tapName, final PhysAddress mac, final Long deviceInstance) {
151         final TapConnect tapConnect = new TapConnect();
152         tapConnect.tapName = tapName.getBytes();
153
154         if (mac == null) {
155             tapConnect.useRandomMac = 1;
156             tapConnect.macAddress = new byte[6];
157         } else {
158             tapConnect.useRandomMac = 0;
159             tapConnect.macAddress = parseMac(mac.getValue());
160         }
161
162         if (deviceInstance == null) {
163             tapConnect.renumber = 0;
164         } else {
165             tapConnect.renumber = 1;
166             tapConnect.customDevInstance = Math.toIntExact(deviceInstance);
167         }
168
169         return tapConnect;
170     }
171
172     private TapModify getTapModifyRequest(final String tapName, final int swIndex, final PhysAddress mac,
173                                           final Long deviceInstance) {
174         final TapModify tapConnect = new TapModify();
175         tapConnect.tapName = tapName.getBytes();
176         tapConnect.swIfIndex = swIndex;
177
178         if (mac == null) {
179             tapConnect.useRandomMac = 1;
180             tapConnect.macAddress = new byte[6];
181         } else {
182             tapConnect.useRandomMac = 0;
183             tapConnect.macAddress = parseMac(mac.getValue());
184         }
185
186         if (deviceInstance == null) {
187             tapConnect.renumber = 0;
188         } else {
189             tapConnect.renumber = 1;
190             tapConnect.customDevInstance = Math.toIntExact(deviceInstance);
191         }
192
193         return tapConnect;
194     }
195
196     private TapDelete getTapDeleteRequest(final int swIndex) {
197         final TapDelete tapConnect = new TapDelete();
198         tapConnect.swIfIndex = swIndex;
199         return tapConnect;
200     }
201 }