YANG revision dates mass-update
[bgpcep.git] / bgp / extensions / mvpn / src / main / java / org / opendaylight / protocol / bgp / mvpn / impl / attributes / PEDistinguisherLabelsAttributeHandler.java
1 /*
2  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.protocol.bgp.mvpn.impl.attributes;
9
10 import static org.opendaylight.protocol.bgp.parser.spi.AttributeUtil.formatAttribute;
11
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.Unpooled;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.opendaylight.protocol.bgp.parser.BGPError;
17 import org.opendaylight.protocol.bgp.parser.BGPTreatAsWithdrawException;
18 import org.opendaylight.protocol.bgp.parser.spi.AbstractAttributeParser;
19 import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
20 import org.opendaylight.protocol.bgp.parser.spi.AttributeUtil;
21 import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
22 import org.opendaylight.protocol.bgp.parser.spi.RevisedErrorHandling;
23 import org.opendaylight.protocol.util.Ipv4Util;
24 import org.opendaylight.protocol.util.Ipv6Util;
25 import org.opendaylight.protocol.util.MplsLabelUtil;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.Attributes;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev200120.bgp.rib.route.PeDistinguisherLabelsAttributeAugmentation;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev200120.bgp.rib.route.PeDistinguisherLabelsAttributeAugmentationBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev200120.pe.distinguisher.labels.attribute.PeDistinguisherLabelsAttribute;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev200120.pe.distinguisher.labels.attribute.PeDistinguisherLabelsAttributeBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev200120.pe.distinguisher.labels.attribute.pe.distinguisher.labels.attribute.PeDistinguisherLabelAttribute;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev200120.pe.distinguisher.labels.attribute.pe.distinguisher.labels.attribute.PeDistinguisherLabelAttributeBuilder;
35 import org.opendaylight.yangtools.yang.binding.DataObject;
36
37 /**
38  * PE Distinguisher Labels Attribute Handler.
39  * https://tools.ietf.org/html/rfc6514#section-8
40  *
41  * @author Claudio D. Gasparini
42  */
43 public final class PEDistinguisherLabelsAttributeHandler extends AbstractAttributeParser
44         implements AttributeSerializer {
45
46     private static final int TYPE = 27;
47
48     public PEDistinguisherLabelsAttributeHandler() {
49     }
50
51     @Override
52     public void parseAttribute(final ByteBuf buffer, final AttributesBuilder builder,
53             final RevisedErrorHandling errorHandling, final PeerSpecificParserConstraint constraint)
54                     throws BGPTreatAsWithdrawException {
55         final int readable = buffer.readableBytes();
56         if (readable == 0) {
57             return;
58         }
59
60         final boolean isIpv4;
61         final int count;
62         if (readable % 7 == 0) {
63             count = readable / 7;
64             isIpv4 = true;
65         } else if (readable % 19 == 0) {
66             count = readable / 19;
67             isIpv4 = false;
68         } else {
69             // RFC-6514 page 16:
70             //        When a router that receives a BGP Update that contains the PE
71             //        Distinguisher Labels attribute with its Partial bit set determines
72             //        that the attribute is malformed, the router SHOULD treat this Update
73             //        as though all the routes contained in this Update had been withdrawn.
74             throw new BGPTreatAsWithdrawException(BGPError.MALFORMED_ATTR_LIST,
75                 "PE Distinguisher Labels has incorrect length %s", readable);
76         }
77
78         final List<PeDistinguisherLabelAttribute> list = new ArrayList<>(count);
79         for (int i = 0; i < count; ++i) {
80             final PeDistinguisherLabelAttributeBuilder attribute = new PeDistinguisherLabelAttributeBuilder();
81             if (isIpv4) {
82                 attribute.setPeAddress(new IpAddressNoZone(Ipv4Util.addressForByteBuf(buffer)));
83             } else {
84                 attribute.setPeAddress(new IpAddressNoZone(Ipv6Util.addressForByteBuf(buffer)));
85             }
86             attribute.setMplsLabel(MplsLabelUtil.mplsLabelForByteBuf(buffer));
87             list.add(attribute.build());
88         }
89
90         builder.addAugmentation(PeDistinguisherLabelsAttributeAugmentation.class,
91                 new PeDistinguisherLabelsAttributeAugmentationBuilder()
92                         .setPeDistinguisherLabelsAttribute(new PeDistinguisherLabelsAttributeBuilder()
93                                 .setPeDistinguisherLabelAttribute(list).build()).build());
94     }
95
96     @Override
97     public void serializeAttribute(final Attributes attribute, final ByteBuf byteAggregator) {
98         final PeDistinguisherLabelsAttributeAugmentation att =
99                 attribute.augmentation(PeDistinguisherLabelsAttributeAugmentation.class);
100
101         if (att == null) {
102             return;
103         }
104
105         final List<PeDistinguisherLabelAttribute> distinguishers
106                 = att.getPeDistinguisherLabelsAttribute().getPeDistinguisherLabelAttribute();
107         final ByteBuf buffer = Unpooled.buffer();
108         for (final PeDistinguisherLabelAttribute peDist : distinguishers) {
109             if (peDist.getPeAddress().getIpv4AddressNoZone() != null) {
110                 buffer.writeBytes(Ipv4Util.bytesForAddress(peDist.getPeAddress().getIpv4AddressNoZone()));
111             } else {
112                 buffer.writeBytes(Ipv6Util.bytesForAddress(peDist.getPeAddress().getIpv6AddressNoZone()));
113             }
114             buffer.writeBytes(MplsLabelUtil.byteBufForMplsLabel(peDist.getMplsLabel()));
115         }
116         formatAttribute(AttributeUtil.OPTIONAL | AttributeUtil.TRANSITIVE, TYPE, buffer, byteAggregator);
117     }
118
119     public int getType() {
120         return TYPE;
121     }
122
123     public Class<? extends DataObject> getClazz() {
124         return PeDistinguisherLabelsAttribute.class;
125     }
126 }