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 static io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils.booleanToByte;
21 import com.google.common.base.Optional;
22 import com.google.common.base.Preconditions;
23 import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer;
24 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
25 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
26 import io.fd.honeycomb.v3po.translate.v3po.util.SubInterfaceUtils;
27 import io.fd.honeycomb.v3po.translate.v3po.util.TagRewriteOperation;
28 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
29 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
30 import io.fd.honeycomb.v3po.translate.write.WriteContext;
31 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
32 import java.util.List;
33 import java.util.concurrent.CompletionStage;
34 import javax.annotation.Nonnull;
35 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1q;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.Rewrite;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.l2.RewriteBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.tag.rewrite.PushTags;
43 import org.opendaylight.yangtools.yang.binding.DataObject;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewrite;
46 import org.openvpp.jvpp.dto.L2InterfaceVlanTagRewriteReply;
47 import org.openvpp.jvpp.future.FutureJVpp;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
52 * Writer Customizer responsible for vlan tag rewrite.<br> Sends {@code l2_interface_vlan_tag_rewrite} message to
53 * VPP.<br> Equivalent of invoking {@code vppctl set interface l2 tag-rewrite} command.
55 public class RewriteCustomizer extends FutureJVppCustomizer implements ChildWriterCustomizer<Rewrite> {
57 private static final Logger LOG = LoggerFactory.getLogger(
58 io.fd.honeycomb.v3po.translate.v3po.interfacesstate.RewriteCustomizer.class);
59 private final NamingContext interfaceContext;
61 public RewriteCustomizer(@Nonnull final FutureJVpp futureJvpp,
62 @Nonnull final NamingContext interfaceContext) {
64 this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
69 public Optional<Rewrite> extract(@Nonnull final InstanceIdentifier<Rewrite> currentId,
70 @Nonnull final DataObject parentData) {
71 return Optional.fromNullable(((L2) parentData).getRewrite());
75 public void writeCurrentAttributes(final InstanceIdentifier<Rewrite> id, final Rewrite dataAfter,
76 final WriteContext writeContext)
77 throws WriteFailedException.CreateFailedException {
80 setTagRewrite(getSubInterfaceName(id), dataAfter, writeContext);
81 } catch (VppApiInvocationException e) {
82 throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
86 private static String getSubInterfaceName(final InstanceIdentifier<Rewrite> id) {
87 return SubInterfaceUtils.getSubInterfaceName(id.firstKeyOf(Interface.class).getName(),
88 Math.toIntExact(id.firstKeyOf(SubInterface.class).getIdentifier()));
91 private void setTagRewrite(final String ifname, final Rewrite rewrite, final WriteContext writeContext)
92 throws VppApiInvocationException {
93 final int swIfIndex = interfaceContext.getIndex(ifname, writeContext.getMappingContext());
94 LOG.debug("Setting tag rewrite for interface {}(id=): {}", ifname, swIfIndex, rewrite);
96 final CompletionStage<L2InterfaceVlanTagRewriteReply> replyCompletionStage =
97 getFutureJVpp().l2InterfaceVlanTagRewrite(getTagRewriteRequest(swIfIndex, rewrite));
99 final L2InterfaceVlanTagRewriteReply reply =
100 TranslateUtils.getReply(replyCompletionStage.toCompletableFuture());
101 if (reply.retval < 0) {
102 LOG.debug("Failed to set tag rewrite for interface {}(id=): {}", ifname, swIfIndex, rewrite);
103 throw new VppApiInvocationException("l2InterfaceVlanTagRewrite", reply.context, reply.retval);
105 LOG.debug("Tag rewrite for interface {}(id=) set successfully: {}", ifname, swIfIndex, rewrite);
109 private L2InterfaceVlanTagRewrite getTagRewriteRequest(final int swIfIndex, final Rewrite rewrite) {
110 final L2InterfaceVlanTagRewrite request = new L2InterfaceVlanTagRewrite();
111 request.swIfIndex = swIfIndex;
112 request.pushDot1Q = booleanToByte(_802dot1q.class == rewrite.getVlanType());
114 final List<PushTags> pushTags = rewrite.getPushTags();
115 final Short popTags = rewrite.getPopTags();
117 final int numberOfTagsToPop = popTags == null
119 : popTags.intValue();
120 final int numberOfTagsToPush = pushTags == null
124 request.vtrOp = TagRewriteOperation.get(numberOfTagsToPop, numberOfTagsToPush).ordinal();
126 if (numberOfTagsToPush > 0) {
127 for (final PushTags tag : pushTags) {
128 if (tag.getIndex() == 0) {
129 request.tag1 = tag.getDot1qTag().getVlanId().getValue();
131 request.tag2 = tag.getDot1qTag().getVlanId().getValue();
136 LOG.debug("Generated tag rewrite request: {}", ReflectionToStringBuilder.toString(request));
141 public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Rewrite> id,
142 @Nonnull final Rewrite dataBefore,
143 @Nonnull final Rewrite dataAfter, @Nonnull final WriteContext writeContext)
144 throws WriteFailedException {
146 setTagRewrite(getSubInterfaceName(id), dataAfter, writeContext);
147 } catch (VppApiInvocationException e) {
148 throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
153 public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Rewrite> id,
154 @Nonnull final Rewrite dataBefore, @Nonnull final WriteContext writeContext)
155 throws WriteFailedException.DeleteFailedException {
157 final String subifName = getSubInterfaceName(id);
158 LOG.debug("Disabling tag rewrite for interface {}", subifName);
159 final Rewrite rewrite = new RewriteBuilder().build(); // rewrite without push and pops will cause delete
160 setTagRewrite(subifName, rewrite, writeContext);
161 } catch (VppApiInvocationException e) {
162 throw new WriteFailedException.DeleteFailedException(id, e);