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.
16 package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip;
18 import static com.google.common.base.Preconditions.checkArgument;
19 import static com.google.common.base.Preconditions.checkNotNull;
21 import com.google.common.base.Optional;
22 import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer;
23 import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
24 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
25 import io.fd.honeycomb.v3po.translate.v3po.util.TranslateUtils;
26 import io.fd.honeycomb.v3po.translate.write.WriteContext;
27 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
28 import java.util.List;
29 import java.util.concurrent.CompletionStage;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.AddressKey;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength;
37 import org.opendaylight.yangtools.yang.binding.DataObject;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.openvpp.jvpp.VppBaseCallException;
40 import org.openvpp.jvpp.dto.SwInterfaceAddDelAddress;
41 import org.openvpp.jvpp.dto.SwInterfaceAddDelAddressReply;
42 import org.openvpp.jvpp.future.FutureJVpp;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * Customizer for writing {@link Address}
51 public class AddressCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<Address, AddressKey> {
53 private static final Logger LOG = LoggerFactory.getLogger(AddressCustomizer.class);
54 private final NamingContext interfaceContext;
56 public AddressCustomizer(FutureJVpp futureJvpp, NamingContext interfaceContext) {
58 this.interfaceContext = interfaceContext;
62 public void writeCurrentAttributes(InstanceIdentifier<Address> id, Address dataAfter, WriteContext writeContext)
63 throws WriteFailedException {
64 setAddress(true, id, dataAfter, writeContext);
68 public void updateCurrentAttributes(InstanceIdentifier<Address> id, Address dataBefore, Address dataAfter,
69 WriteContext writeContext) throws WriteFailedException {
70 throw new WriteFailedException.UpdateFailedException(id,dataBefore,dataAfter,new UnsupportedOperationException("Operation not supported"));
74 public void deleteCurrentAttributes(InstanceIdentifier<Address> id, Address dataBefore, WriteContext writeContext)
75 throws WriteFailedException {
76 setAddress(false, id, dataBefore, writeContext);
80 public Optional<List<Address>> extract(InstanceIdentifier<Address> currentId, DataObject parentData) {
81 return Optional.fromNullable((((Ipv4)parentData).getAddress()));
84 private void setAddress(boolean add,final InstanceIdentifier<Address> id, final Address address,
85 final WriteContext writeContext) throws WriteFailedException {
87 final String interfaceName = id.firstKeyOf(Interface.class).getName();
88 final int swIfc = interfaceContext.getIndex(interfaceName, writeContext.getMappingContext());
90 Subnet subnet = address.getSubnet();
92 if (subnet instanceof PrefixLength) {
93 setPrefixLengthSubnet(add,id, interfaceName, swIfc, address, (PrefixLength) subnet);
94 } else if (subnet instanceof Netmask) {
97 // FIXME how does choice extensibility work
98 // FIXME it is not even possible to create a dedicated
99 // customizer for Interconnection, since it's not a DataObject
100 // FIXME we might need a choice customizer
101 // THis choice is already from augment, so its probably not
102 // possible to augment augmented choice
103 LOG.error("Unable to handle subnet of type {}", subnet.getClass());
104 throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass());
108 private void setNetmaskSubnet() {
110 throw new UnsupportedOperationException("Unimplemented");
113 private void setPrefixLengthSubnet(boolean add,final InstanceIdentifier<Address> id, final String name, final int swIfc,
114 final Address address, final PrefixLength subnet) throws WriteFailedException {
116 Short plen = subnet.getPrefixLength();
117 LOG.debug("Setting Subnet(prefix-length) for interface: {}, {}. Subnet: {}, Address: {}", name, swIfc,
120 byte[] addr = TranslateUtils.ipv4AddressNoZoneToArray(address.getIp());
122 checkArgument(plen > 0, "Invalid length");
123 checkNotNull(addr, "Null address");
125 final CompletionStage<SwInterfaceAddDelAddressReply> swInterfaceAddDelAddressReplyCompletionStage = getFutureJVpp()
126 .swInterfaceAddDelAddress(getSwInterfaceAddDelAddressRequest(swIfc, TranslateUtils.booleanToByte(add) /* isAdd */,
127 (byte) 0 /* isIpv6 */, (byte) 0 /* delAll */, plen.byteValue(), addr));
129 TranslateUtils.getReply(swInterfaceAddDelAddressReplyCompletionStage.toCompletableFuture());
131 LOG.debug("Subnet(prefix-length) set successfully for interface: {}, {}, Subnet: {}, Address: {}", name,
132 swIfc, subnet, address);
133 } catch (VppBaseCallException e) {
134 LOG.warn("Failed to set Subnet(prefix-length) for interface: {}, {}, Subnet: {}, Address: {}", name, swIfc,
136 throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass(), e);
140 private SwInterfaceAddDelAddress getSwInterfaceAddDelAddressRequest(final int swIfc, final byte isAdd,
141 final byte ipv6, final byte deleteAll, final byte length, final byte[] addr) {
142 final SwInterfaceAddDelAddress swInterfaceAddDelAddress = new SwInterfaceAddDelAddress();
143 swInterfaceAddDelAddress.swIfIndex = swIfc;
144 swInterfaceAddDelAddress.isAdd = isAdd;
145 swInterfaceAddDelAddress.isIpv6 = ipv6;
146 swInterfaceAddDelAddress.delAll = deleteAll;
147 swInterfaceAddDelAddress.address = addr;
148 swInterfaceAddDelAddress.addressLength = length;
149 return swInterfaceAddDelAddress;