2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bgp.evpn.impl.nlri;
10 import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.parseRouteDistinguisher;
11 import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.serializeRouteDistinquisher;
12 import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractRouteDistinguisher;
14 import com.google.common.base.Preconditions;
15 import io.netty.buffer.ByteBuf;
16 import io.netty.buffer.Unpooled;
17 import java.util.ArrayList;
18 import java.util.List;
19 import javax.annotation.Nullable;
20 import org.opendaylight.protocol.bgp.evpn.spi.EvpnRegistry;
21 import org.opendaylight.protocol.bgp.evpn.spi.pojo.SimpleEvpnNlriRegistry;
22 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
23 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
24 import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.NlriType;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.evpn.EvpnChoice;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.evpn.destination.EvpnDestination;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.evpn.destination.EvpnDestinationBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationEvpnCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationEvpnCaseBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.evpn._case.DestinationEvpnBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes1;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes2;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpReachNlriBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpUnreachNlri;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpUnreachNlriBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.reach.nlri.AdvertizedRoutes;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
42 import org.opendaylight.yangtools.yang.binding.DataObject;
43 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
44 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
45 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
46 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 public final class EvpnNlriParser implements NlriParser, NlriSerializer {
51 private static final Logger LOG = LoggerFactory.getLogger(EvpnNlriParser.class);
52 private static final NodeIdentifier EVPN_CHOICE_NID = new NodeIdentifier(EvpnChoice.QNAME);
55 private interface ExtractionInterface {
56 EvpnChoice check(EvpnRegistry reg, ChoiceNode cont);
59 public static EvpnDestination extractEvpnDestination(final DataContainerNode<? extends PathArgument> evpnChoice) {
60 return extractDestination(evpnChoice, EvpnRegistry::serializeEvpnModel);
63 private static EvpnDestination extractDestination(final DataContainerNode<? extends PathArgument> evpnChoice,
64 final ExtractionInterface extract) {
65 final EvpnRegistry reg = SimpleEvpnNlriRegistry.getInstance();
66 final ChoiceNode cont = (ChoiceNode) evpnChoice.getChild(EVPN_CHOICE_NID).get();
67 final EvpnChoice evpnValue = extract.check(reg, cont);
68 if (evpnValue == null) {
69 LOG.warn("Unrecognized Nlri {}", cont);
72 return new EvpnDestinationBuilder().setRouteDistinguisher(extractRouteDistinguisher(evpnChoice))
73 .setEvpnChoice(evpnValue).build();
76 public static EvpnDestination extractRouteKeyDestination(
77 final DataContainerNode<? extends PathArgument> evpnChoice) {
78 return extractDestination(evpnChoice, EvpnRegistry::serializeEvpnRouteKey);
82 public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder) throws BGPParsingException {
83 if (!nlri.isReadable()) {
86 final List<EvpnDestination> dst = parseNlri(nlri);
88 builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
89 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.update.attributes
90 .mp.unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCaseBuilder()
91 .setDestinationEvpn(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn
92 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination
93 .evpn._case.DestinationEvpnBuilder().setEvpnDestination(dst).build()).build()).build());
97 public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder) throws BGPParsingException {
98 if (!nlri.isReadable()) {
101 final List<EvpnDestination> dst = parseNlri(nlri);
103 builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
104 new DestinationEvpnCaseBuilder().setDestinationEvpn(new DestinationEvpnBuilder()
105 .setEvpnDestination(dst).build()).build()).build());
109 private static List<EvpnDestination> parseNlri(final ByteBuf nlri) {
110 if (!nlri.isReadable()) {
113 final List<EvpnDestination> dests = new ArrayList<>();
115 while (nlri.isReadable()) {
116 final EvpnDestinationBuilder builder = new EvpnDestinationBuilder();
117 final NlriType type = NlriType.forValue(nlri.readUnsignedByte());
118 final int length = nlri.readUnsignedByte();
119 final ByteBuf nlriBuf = nlri.readSlice(length);
120 builder.setRouteDistinguisher(parseRouteDistinguisher(nlriBuf));
121 builder.setEvpnChoice(SimpleEvpnNlriRegistry.getInstance().parseEvpn(type, nlriBuf));
122 dests.add(builder.build());
128 public void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) {
129 Preconditions.checkArgument(attribute instanceof Attributes, "Attribute parameter is not a Attributes object");
130 final Attributes pathAttributes = (Attributes) attribute;
131 final Attributes1 pathAttributes1 = pathAttributes.getAugmentation(Attributes1.class);
132 final Attributes2 pathAttributes2 = pathAttributes.getAugmentation(Attributes2.class);
133 if (pathAttributes1 != null) {
134 final AdvertizedRoutes routes = pathAttributes1.getMpReachNlri().getAdvertizedRoutes();
135 if (routes != null && routes.getDestinationType() instanceof DestinationEvpnCase) {
136 final DestinationEvpnCase evpnCase = (DestinationEvpnCase) routes.getDestinationType();
137 serializeNlri(evpnCase.getDestinationEvpn().getEvpnDestination(), byteAggregator);
139 } else if (pathAttributes2 != null) {
140 final MpUnreachNlri mpUnreachNlri = pathAttributes2.getMpUnreachNlri();
141 final WithdrawnRoutes withdrawnRoutes = mpUnreachNlri.getWithdrawnRoutes();
142 if (withdrawnRoutes != null && withdrawnRoutes.getDestinationType()
143 instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329
144 .update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCase) {
145 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.update
146 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCase evpnCase =
147 (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.update
148 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type
149 .DestinationEvpnCase) mpUnreachNlri.getWithdrawnRoutes().getDestinationType();
150 serializeNlri(evpnCase.getDestinationEvpn().getEvpnDestination(), byteAggregator);
155 public static void serializeNlri(final List<EvpnDestination> destinationList, final ByteBuf output) {
156 ByteBuf nlriOutput = null;
157 for (final EvpnDestination dest : destinationList) {
158 final ByteBuf nlriCommon = Unpooled.buffer();
159 serializeRouteDistinquisher(dest.getRouteDistinguisher(), nlriCommon);
160 nlriOutput = SimpleEvpnNlriRegistry.getInstance().serializeEvpn(dest.getEvpnChoice(), nlriCommon);
162 output.writeBytes(nlriOutput);