Eliminate use of ByteBufWriteUtil from route-target
[bgpcep.git] / bgp / extensions / route-target / src / main / java / org / opendaylight / protocol / bgp / route / targetcontrain / impl / nlri / RouteTargetConstrainNlriHandler.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.route.targetcontrain.impl.nlri;
9
10 import io.netty.buffer.ByteBuf;
11 import io.netty.buffer.Unpooled;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
15 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
16 import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupportUtil;
17 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
18 import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
19 import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
20 import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutes;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.RouteTargetConstrainChoice;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.destination.RouteTargetConstrainDestination;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.destination.RouteTargetConstrainDestinationBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.route.target.constrain.choice.RouteTargetConstrainDefaultCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationRouteTargetConstrainAdvertizedCase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationRouteTargetConstrainAdvertizedCaseBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.route.target.constrain.advertized._case.DestinationRouteTargetConstrainBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationRouteTargetConstrainWithdrawnCase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationRouteTargetConstrainWithdrawnCaseBuilder;
40 import org.opendaylight.yangtools.yang.common.netty.ByteBufUtils;
41
42 /**
43  * Route Target Nlri Handler.
44  *
45  * @author Claudio D. Gasparini
46  */
47 public final class RouteTargetConstrainNlriHandler implements NlriParser, NlriSerializer {
48     private static final short RT_BITS_LENGTH = 96;
49
50     private static List<RouteTargetConstrainDestination> parseNlriDestinations(final ByteBuf nlri,
51             final boolean addPathSupported) {
52         final List<RouteTargetConstrainDestination> dests = new ArrayList<>();
53
54         while (nlri.isReadable()) {
55             final RouteTargetConstrainDestinationBuilder builder = new RouteTargetConstrainDestinationBuilder();
56             if (addPathSupported) {
57                 builder.setPathId(PathIdUtil.readPathId(nlri));
58             }
59             final int length = nlri.readUnsignedByte() / 8;
60             final ByteBuf nlriBuf = nlri.readSlice(length);
61             Integer type = null;
62             if (length != 0) {
63                 builder.setOriginAs(new AsNumber(ByteBufUtils.readUint32(nlriBuf)));
64                 type = (int) nlriBuf.readUnsignedByte();
65                 //Skip Subtype
66                 nlriBuf.skipBytes(1);
67             }
68             builder.setRouteTargetConstrainChoice(SimpleRouteTargetConstrainNlriRegistry.getInstance()
69                     .parseRouteTargetConstrain(type, nlriBuf));
70             dests.add(builder.build());
71         }
72         return dests;
73     }
74
75     public static ByteBuf serializeNlriDestinations(final List<RouteTargetConstrainDestination> destinationList) {
76         final ByteBuf nlri = Unpooled.buffer();
77         for (final RouteTargetConstrainDestination dest : destinationList) {
78             final RouteTargetConstrainChoice rtcChoice = dest.getRouteTargetConstrainChoice();
79             if (rtcChoice instanceof RouteTargetConstrainDefaultCase) {
80                 nlri.writeByte(0);
81             } else {
82                 nlri.writeByte(RT_BITS_LENGTH);
83                 final AsNumber originAs = dest.getOriginAs();
84                 if (originAs != null) {
85                     ByteBufUtils.write(nlri, originAs.getValue());
86                 }
87                 nlri.writeBytes(SimpleRouteTargetConstrainNlriRegistry.getInstance()
88                         .serializeRouteTargetConstrain(rtcChoice));
89             }
90         }
91         return nlri;
92     }
93
94     @Override
95     public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder,
96             final PeerSpecificParserConstraint constraint) throws BGPParsingException {
97         if (!nlri.isReadable()) {
98             return;
99         }
100         final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint,
101                 new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
102         builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder()
103                 .setDestinationType(new DestinationRouteTargetConstrainAdvertizedCaseBuilder()
104                         .setDestinationRouteTargetConstrain(new DestinationRouteTargetConstrainBuilder()
105                                 .setRouteTargetConstrainDestination(parseNlriDestinations(nlri, mPathSupported))
106                                 .build()).build()).build());
107     }
108
109     @Override
110     public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder,
111             final PeerSpecificParserConstraint constraint) throws BGPParsingException {
112         if (!nlri.isReadable()) {
113             return;
114         }
115         final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint,
116                 new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
117         builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder()
118                 .setDestinationType(new DestinationRouteTargetConstrainWithdrawnCaseBuilder()
119                         .setDestinationRouteTargetConstrain(new org.opendaylight.yang.gen.v1.urn.opendaylight.params
120                                 .xml.ns.yang.bgp.route.target.constrain.rev180618.update
121                                 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type
122                                 .destination.route.target.constrain
123                                 .withdrawn._case.DestinationRouteTargetConstrainBuilder()
124                                 .setRouteTargetConstrainDestination(parseNlriDestinations(nlri, mPathSupported))
125                                 .build()).build()).build());
126     }
127
128     @Override
129     public void serializeAttribute(final Attributes pathAttributes, final ByteBuf byteAggregator) {
130         final Attributes1 pathAttributes1 = pathAttributes.augmentation(Attributes1.class);
131         final Attributes2 pathAttributes2 = pathAttributes.augmentation(Attributes2.class);
132         if (pathAttributes1 != null) {
133             final AdvertizedRoutes routes = pathAttributes1.getMpReachNlri().getAdvertizedRoutes();
134             if (routes != null && routes.getDestinationType()
135                     instanceof DestinationRouteTargetConstrainAdvertizedCase) {
136                 final DestinationRouteTargetConstrainAdvertizedCase reach
137                         = (DestinationRouteTargetConstrainAdvertizedCase) routes.getDestinationType();
138                 byteAggregator.writeBytes(serializeNlriDestinations(reach.getDestinationRouteTargetConstrain()
139                         .getRouteTargetConstrainDestination()));
140             }
141         } else if (pathAttributes2 != null) {
142             final WithdrawnRoutes withdrawnRoutes = pathAttributes2.getMpUnreachNlri().getWithdrawnRoutes();
143             if (withdrawnRoutes != null
144                     && withdrawnRoutes.getDestinationType() instanceof DestinationRouteTargetConstrainWithdrawnCase) {
145                 final DestinationRouteTargetConstrainWithdrawnCase reach
146                         = (DestinationRouteTargetConstrainWithdrawnCase) withdrawnRoutes.getDestinationType();
147                 byteAggregator.writeBytes(serializeNlriDestinations(reach.getDestinationRouteTargetConstrain()
148                         .getRouteTargetConstrainDestination()));
149             }
150         }
151     }
152 }