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