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.translate.v3po.vpp;
19 import com.google.common.base.Preconditions;
20 import com.google.common.primitives.Longs;
21 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
22 import io.fd.honeycomb.translate.vpp.util.ByteDataTranslator;
23 import io.fd.honeycomb.translate.vpp.util.FutureJVppCustomizer;
24 import io.fd.honeycomb.translate.vpp.util.JvppReplyConsumer;
25 import io.fd.honeycomb.translate.vpp.util.MacTranslator;
26 import io.fd.honeycomb.translate.vpp.util.NamingContext;
27 import io.fd.honeycomb.translate.vpp.util.WriteTimeoutException;
28 import io.fd.honeycomb.translate.write.WriteContext;
29 import io.fd.honeycomb.translate.write.WriteFailedException;
30 import java.util.concurrent.CompletionStage;
31 import javax.annotation.Nonnull;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.L2FibFilter;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntry;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.fib.attributes.l2.fib.table.L2FibEntryKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.openvpp.jvpp.VppBaseCallException;
38 import org.openvpp.jvpp.core.dto.L2FibAddDel;
39 import org.openvpp.jvpp.core.dto.L2FibAddDelReply;
40 import org.openvpp.jvpp.core.future.FutureJVppCore;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
45 * Writer Customizer responsible for L2 FIB create/delete operations.<br> Sends {@code l2_fib_add_del} message to
46 * VPP.<br> Equivalent of invoking {@code vppctl l2fib add/del} command.
48 public class L2FibEntryCustomizer extends FutureJVppCustomizer
49 implements ListWriterCustomizer<L2FibEntry, L2FibEntryKey>, ByteDataTranslator, MacTranslator,
52 private static final Logger LOG = LoggerFactory.getLogger(L2FibEntryCustomizer.class);
54 private final NamingContext bdContext;
55 private final NamingContext interfaceContext;
57 public L2FibEntryCustomizer(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull final NamingContext bdContext,
58 @Nonnull final NamingContext interfaceContext) {
59 super(futureJVppCore);
60 this.bdContext = Preconditions.checkNotNull(bdContext, "bdContext should not be null");
61 this.interfaceContext = Preconditions.checkNotNull(interfaceContext, "interfaceContext should not be null");
65 public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<L2FibEntry> id,
66 @Nonnull final L2FibEntry dataAfter, @Nonnull final WriteContext writeContext)
67 throws WriteFailedException {
69 LOG.debug("Creating L2 FIB entry: {} {}", id, dataAfter);
70 l2FibAddDel(id, dataAfter, writeContext, true);
71 LOG.debug("L2 FIB entry created successfully: {} {}", id, dataAfter);
72 } catch (VppBaseCallException e) {
73 LOG.warn("Failed to create L2 FIB entry: {} {}", id, dataAfter);
74 throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
79 public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<L2FibEntry> id,
80 @Nonnull final L2FibEntry dataBefore, @Nonnull final L2FibEntry dataAfter,
81 @Nonnull final WriteContext writeContext) throws WriteFailedException {
82 throw new UnsupportedOperationException(
83 "L2 FIB entry update is not supported. It has to be deleted and then created.");
87 public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<L2FibEntry> id,
88 @Nonnull final L2FibEntry dataBefore, @Nonnull final WriteContext writeContext)
89 throws WriteFailedException {
91 LOG.debug("Deleting L2 FIB entry: {} {}", id, dataBefore);
92 l2FibAddDel(id, dataBefore, writeContext, false);
93 LOG.debug("L2 FIB entry deleted successfully: {} {}", id, dataBefore);
94 } catch (VppBaseCallException e) {
95 LOG.warn("Failed to delete L2 FIB entry: {} {}", id, dataBefore);
96 throw new WriteFailedException.DeleteFailedException(id, e);
100 private void l2FibAddDel(@Nonnull final InstanceIdentifier<L2FibEntry> id, @Nonnull final L2FibEntry entry,
101 final WriteContext writeContext, boolean isAdd)
102 throws VppBaseCallException, WriteTimeoutException {
103 final String bdName = id.firstKeyOf(BridgeDomain.class).getName();
104 final int bdId = bdContext.getIndex(bdName, writeContext.getMappingContext());
107 final String swIfName = entry.getOutgoingInterface();
108 if (swIfName != null) {
109 swIfIndex = interfaceContext.getIndex(swIfName, writeContext.getMappingContext());
112 final L2FibAddDel l2FibRequest = createL2FibRequest(entry, bdId, swIfIndex, isAdd);
113 LOG.debug("Sending l2FibAddDel request: {}", l2FibRequest);
114 final CompletionStage<L2FibAddDelReply> l2FibAddDelReplyCompletionStage =
115 getFutureJVpp().l2FibAddDel(l2FibRequest);
117 getReplyForWrite(l2FibAddDelReplyCompletionStage.toCompletableFuture(), id);
120 private L2FibAddDel createL2FibRequest(final L2FibEntry entry, final int bdId, final int swIfIndex, boolean isAdd) {
121 final L2FibAddDel request = new L2FibAddDel();
122 request.mac = macToLong(entry.getPhysAddress().getValue());
124 request.swIfIndex = swIfIndex;
125 request.isAdd = booleanToByte(isAdd);
127 request.staticMac = booleanToByte(entry.isStaticConfig());
128 request.filterMac = booleanToByte(L2FibFilter.class == entry.getAction());
133 // mac address is string of the form: 11:22:33:44:55:66
134 // but VPP expects long value in the format 11:22:33:44:55:66:XX:XX
135 private long macToLong(final String macAddress) {
136 final byte[] mac = parseMac(macAddress);
137 return Longs.fromBytes(mac[0], mac[1], mac[2], mac[3],
138 mac[4], mac[5], (byte) 0, (byte) 0);