Provide Add Path support for all AFI/SAFI
[bgpcep.git] / bgp / inet / src / main / java / org / opendaylight / protocol / bgp / inet / codec / Ipv4NlriParser.java
1 /*
2  * Copyright (c) 2013, 2016 Cisco Systems, Inc. and others.  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.inet.codec;
10
11 import com.google.common.base.Preconditions;
12 import io.netty.buffer.ByteBuf;
13 import java.util.ArrayList;
14 import java.util.List;
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.protocol.util.ByteBufWriteUtil;
22 import org.opendaylight.protocol.util.Ipv4Util;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.prefixes.DestinationIpv4;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.prefixes.DestinationIpv4Builder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.prefixes.destination.ipv4.Ipv4Prefixes;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.prefixes.destination.ipv4.Ipv4PrefixesBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationIpv4Case;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationIpv4CaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes1;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes2;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpReachNlriBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpUnreachNlriBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.reach.nlri.AdvertizedRoutes;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
40 import org.opendaylight.yangtools.yang.binding.DataObject;
41
42 public final class Ipv4NlriParser implements NlriParser, NlriSerializer {
43
44     private static DestinationIpv4 prefixes(final ByteBuf nlri, final PeerSpecificParserConstraint constraints,
45             final Class<? extends AddressFamily> afi, final Class<? extends SubsequentAddressFamily> safi) {
46         final List<Ipv4Prefixes> prefixes = new ArrayList<>();
47         while (nlri.isReadable()) {
48             final Ipv4PrefixesBuilder prefixesBuilder = new Ipv4PrefixesBuilder();
49             if (MultiPathSupportUtil.isTableTypeSupported(constraints, new BgpTableTypeImpl(afi, safi))) {
50                 prefixesBuilder.setPathId(PathIdUtil.readPathId(nlri));
51             }
52             prefixesBuilder.setPrefix(Ipv4Util.prefixForByteBuf(nlri));
53             prefixes.add(prefixesBuilder.build());
54         }
55         return new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build();
56     }
57
58     @Override
59     public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder) {
60         parseNlri(nlri, builder, null);
61     }
62
63     @Override
64     public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder) {
65         parseNlri(nlri, builder, null);
66     }
67
68     @Override
69     public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder,
70             final PeerSpecificParserConstraint constraint) {
71         builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
72                 new DestinationIpv4CaseBuilder().setDestinationIpv4(prefixes(nlri, constraint,
73                         builder.getAfi(), builder.getSafi())).build()).build());
74     }
75
76     @Override
77     public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder,
78             final PeerSpecificParserConstraint constraint) {
79         builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
80                 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.update
81                         .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationIpv4CaseBuilder()
82                         .setDestinationIpv4(prefixes(nlri, constraint, builder.getAfi(), builder.getSafi()))
83                         .build()).build());
84     }
85
86     @Override
87     public void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) {
88         Preconditions.checkArgument(attribute instanceof Attributes,
89                 "Attribute parameter is not a PathAttribute object.");
90         final Attributes pathAttributes = (Attributes) attribute;
91         final Attributes1 pathAttributes1 = pathAttributes.getAugmentation(Attributes1.class);
92         final Attributes2 pathAttributes2 = pathAttributes.getAugmentation(Attributes2.class);
93         if (pathAttributes1 != null) {
94             final AdvertizedRoutes advertizedRoutes = pathAttributes1.getMpReachNlri().getAdvertizedRoutes();
95             if (advertizedRoutes != null && advertizedRoutes.getDestinationType() instanceof DestinationIpv4Case) {
96                 final DestinationIpv4Case destinationIpv4Case =
97                         (DestinationIpv4Case) advertizedRoutes.getDestinationType();
98                 for (final Ipv4Prefixes ipv4Prefix : destinationIpv4Case.getDestinationIpv4().getIpv4Prefixes()) {
99                     PathIdUtil.writePathId(ipv4Prefix.getPathId(), byteAggregator);
100                     ByteBufWriteUtil.writeMinimalPrefix(ipv4Prefix.getPrefix(), byteAggregator);
101                 }
102             }
103         } else if (pathAttributes2 != null) {
104             final WithdrawnRoutes withdrawnRoutes = pathAttributes2.getMpUnreachNlri().getWithdrawnRoutes();
105             if (withdrawnRoutes != null && withdrawnRoutes.getDestinationType() instanceof org.opendaylight.yang.gen
106                     .v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.update.attributes.mp.unreach.nlri
107                     .withdrawn.routes.destination.type.DestinationIpv4Case) {
108                 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.update
109                         .attributes.mp.unreach.nlri.withdrawn.routes.destination.type
110                         .DestinationIpv4Case destinationIpv4Case = (org.opendaylight.yang.gen.v1.urn.opendaylight
111                         .params.xml.ns.yang.bgp.inet.rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes
112                         .destination.type.DestinationIpv4Case) withdrawnRoutes.getDestinationType();
113                 for (final Ipv4Prefixes ipv4Prefix : destinationIpv4Case.getDestinationIpv4().getIpv4Prefixes()) {
114                     PathIdUtil.writePathId(ipv4Prefix.getPathId(), byteAggregator);
115                     ByteBufWriteUtil.writeMinimalPrefix(ipv4Prefix.getPrefix(), byteAggregator);
116                 }
117             }
118         }
119     }
120 }