From df5897dcd8e158e2ac4469782c72b6481fb15ec4 Mon Sep 17 00:00:00 2001 From: "Claudio D. Gasparini" Date: Tue, 5 Apr 2016 11:24:28 +0200 Subject: [PATCH] BUG-4826: BGP Evpn Nlri's handlers Evpn Nlri cases handlers https://tools.ietf.org/html/rfc7432#section-7 Change-Id: I385e20a0e510328761c1f341a8c7744182dc5850 Signed-off-by: Claudio D. Gasparini --- .../bgp/evpn/{ => impl}/BGPActivator.java | 18 +- .../bgp/evpn/impl/nlri/AbstractEvpnNlri.java | 47 ++++++ .../bgp/evpn/impl/nlri/EthADRParser.java | 89 ++++++++++ .../bgp/evpn/impl/nlri/EthSegRParser.java | 104 ++++++++++++ .../bgp/evpn/impl/nlri/EvpnNlriParser.java | 154 ++++++++++++++++++ .../evpn/impl/nlri/IncMultEthTagRParser.java | 79 +++++++++ .../bgp/evpn/impl/nlri/MACIpAdvRParser.java | 149 +++++++++++++++++ .../bgp/evpn/impl/nlri/NlriActivator.java | 49 ++++++ .../bgp/evpn/impl/nlri/NlriModelUtil.java | 72 ++++++++ 9 files changed, 758 insertions(+), 3 deletions(-) rename bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/{ => impl}/BGPActivator.java (81%) create mode 100644 bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/AbstractEvpnNlri.java create mode 100644 bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EthADRParser.java create mode 100644 bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EthSegRParser.java create mode 100644 bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EvpnNlriParser.java create mode 100644 bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/IncMultEthTagRParser.java create mode 100644 bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/MACIpAdvRParser.java create mode 100644 bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/NlriActivator.java create mode 100644 bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/NlriModelUtil.java diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/BGPActivator.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/BGPActivator.java similarity index 81% rename from bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/BGPActivator.java rename to bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/BGPActivator.java index 6ec8eaefc5..8ebe425145 100644 --- a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/BGPActivator.java +++ b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/BGPActivator.java @@ -5,7 +5,8 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.protocol.bgp.evpn; + +package org.opendaylight.protocol.bgp.evpn.impl; import java.util.ArrayList; import java.util.List; @@ -14,19 +15,28 @@ import org.opendaylight.protocol.bgp.evpn.impl.extended.communities.DefaultGatew import org.opendaylight.protocol.bgp.evpn.impl.extended.communities.ESILabelExtCom; import org.opendaylight.protocol.bgp.evpn.impl.extended.communities.ESImpRouteTargetExtCom; import org.opendaylight.protocol.bgp.evpn.impl.extended.communities.MACMobExtCom; +import org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriActivator; import org.opendaylight.protocol.bgp.parser.spi.AbstractBGPExtensionProviderActivator; import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.EvpnSubsequentAddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.L2vpnAddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.evpn.routes.evpn.route.attributes.extended.communities.extended.community.DefaultGatewayExtendedCommunityCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.extended.communities.extended.community.EsImportRouteExtendedCommunityCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.extended.communities.extended.community.EsiLabelExtendedCommunityCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.extended.communities.extended.community.MacMobilityExtendedCommunityCase; +public final class BGPActivator extends AbstractBGPExtensionProviderActivator { + private static final int L2VPN_AFI = 25; + private static final int EVPN_SAFI = 70; -public class BGPActivator extends AbstractBGPExtensionProviderActivator { @Override protected List startImpl(final BGPExtensionProviderContext context) { final List regs = new ArrayList<>(); + regs.add(context.registerSubsequentAddressFamily(EvpnSubsequentAddressFamily.class, EVPN_SAFI)); + regs.add(context.registerAddressFamily(L2vpnAddressFamily.class, L2VPN_AFI)); + + NlriActivator.registerNlriParsers(regs); registerExtendedCommunities(context, regs); ESIActivator.registerEsiTypeParsers(regs); return regs; @@ -49,4 +59,6 @@ public class BGPActivator extends AbstractBGPExtensionProviderActivator { regs.add(context.registerExtendedCommunityParser(macEC.getType(true), macEC.getSubType(), macEC)); regs.add(context.registerExtendedCommunitySerializer(MacMobilityExtendedCommunityCase.class, macEC)); } -} \ No newline at end of file + + +} diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/AbstractEvpnNlri.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/AbstractEvpnNlri.java new file mode 100644 index 0000000000..4d58c7884c --- /dev/null +++ b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/AbstractEvpnNlri.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.protocol.bgp.evpn.impl.nlri; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.bgp.evpn.spi.EvpnParser; +import org.opendaylight.protocol.bgp.evpn.spi.EvpnSerializer; +import org.opendaylight.protocol.bgp.evpn.spi.pojo.SimpleEsiTypeRegistry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.NlriType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.esi.Esi; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.EvpnChoice; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; + +abstract class AbstractEvpnNlri implements EvpnParser, EvpnSerializer { + + static final int MAC_ADDRESS_LENGTH = 6; + static final int ESI_SIZE = 10; + private static final NodeIdentifier ESI_NID = NodeIdentifier.create(Esi.QNAME); + static final int ZERO_BYTE = 1; + + @Override + public final ByteBuf serializeEvpn(final EvpnChoice evpn, final ByteBuf common) { + final ByteBuf output = Unpooled.buffer(); + final ByteBuf body = serializeBody(evpn); + output.writeByte(getType().getIntValue()); + output.writeByte(body.readableBytes() + common.readableBytes()); + output.writeBytes(common); + output.writeBytes(body); + return output; + } + + protected abstract NlriType getType(); + + protected abstract ByteBuf serializeBody(final EvpnChoice evpn); + + protected static Esi serializeEsi(final ContainerNode evpn) { + return SimpleEsiTypeRegistry.getInstance().parseEsiModel((ChoiceNode) evpn.getChild(ESI_NID).get()); + } +} diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EthADRParser.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EthADRParser.java new file mode 100644 index 0000000000..9df01a0fdd --- /dev/null +++ b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EthADRParser.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.protocol.bgp.evpn.impl.nlri; + +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.MPLS_NID; +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractETI; +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractMplsLabel; +import static org.opendaylight.protocol.util.MplsLabelUtil.byteBufForMplsLabel; +import static org.opendaylight.protocol.util.MplsLabelUtil.mplsLabelForByteBuf; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.bgp.evpn.spi.pojo.SimpleEsiTypeRegistry; +import org.opendaylight.protocol.util.ByteBufWriteUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.NlriType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.esi.Esi; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.a.d.route.EthernetADRoute; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.a.d.route.EthernetADRouteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.tag.id.EthernetTagId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.tag.id.EthernetTagIdBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.EvpnChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.EthernetADRouteCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.EthernetADRouteCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; + +final class EthADRParser extends AbstractEvpnNlri { + protected static final NodeIdentifier ETH_AD_ROUTE_NID = new NodeIdentifier(EthernetADRoute.QNAME); + private static final int CONTENT_LENGTH = 17; + + @Override + public EvpnChoice parseEvpn(final ByteBuf buffer) { + Preconditions.checkArgument(buffer.readableBytes() == CONTENT_LENGTH, "Wrong length of array of bytes. Passed: %s ;", buffer); + final Esi esi = SimpleEsiTypeRegistry.getInstance().parseEsi(buffer.readSlice(ESI_SIZE)); + final EthernetTagId eti = new EthernetTagIdBuilder().setVlanId(buffer.readUnsignedInt()).build(); + final MplsLabel label = mplsLabelForByteBuf(buffer); + final EthernetADRouteBuilder builder = new EthernetADRouteBuilder().setEsi(esi).setEthernetTagId(eti).setMplsLabel(label); + return new EthernetADRouteCaseBuilder().setEthernetADRoute(builder.build()).build(); + } + + @Override + protected NlriType getType() { + return NlriType.EthADDisc; + } + + @Override + public ByteBuf serializeBody(final EvpnChoice evpn) { + Preconditions.checkArgument(evpn instanceof EthernetADRouteCase, "Unknown evpn instance. Passed %s. Needed EthernetADRouteCase.", evpn.getClass()); + return serializeBody(((EthernetADRouteCase) evpn).getEthernetADRoute()); + } + + @Override + public EvpnChoice serializeEvpnModel(final ContainerNode evpn) { + final EthernetADRouteBuilder builder = serializeKeyModel(evpn); + builder.setMplsLabel(extractMplsLabel(evpn, MPLS_NID)); + return new EthernetADRouteCaseBuilder().setEthernetADRoute(builder.build()).build(); + } + + @Override + public EvpnChoice createRouteKey(final ContainerNode evpn) { + return new EthernetADRouteCaseBuilder().setEthernetADRoute(serializeKeyModel(evpn).build()).build(); + } + + private static EthernetADRouteBuilder serializeKeyModel(final ContainerNode evpn) { + final EthernetADRouteBuilder builder = new EthernetADRouteBuilder(); + builder.setEsi(serializeEsi(evpn)); + builder.setEthernetTagId(extractETI(evpn)); + return builder; + } + + private static ByteBuf serializeBody(final EthernetADRoute evpn) { + final ByteBuf body = Unpooled.buffer(CONTENT_LENGTH); + SimpleEsiTypeRegistry.getInstance().serializeEsi(evpn.getEsi(), body); + ByteBufWriteUtil.writeUnsignedInt(evpn.getEthernetTagId().getVlanId(), body); + + final MplsLabel mpls = evpn.getMplsLabel(); + if (mpls != null) { + body.writeBytes(byteBufForMplsLabel(evpn.getMplsLabel())); + } + return body; + } +} \ No newline at end of file diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EthSegRParser.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EthSegRParser.java new file mode 100644 index 0000000000..0ffe8683e5 --- /dev/null +++ b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EthSegRParser.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.protocol.bgp.evpn.impl.nlri; + +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractOrigRouteIp; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.bgp.evpn.spi.pojo.SimpleEsiTypeRegistry; +import org.opendaylight.protocol.util.Ipv4Util; +import org.opendaylight.protocol.util.Ipv6Util; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.NlriType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.es.route.EsRoute; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.es.route.EsRouteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.esi.Esi; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.EvpnChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.EsRouteCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.EsRouteCaseBuilder; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; + +final class EthSegRParser extends AbstractEvpnNlri { + protected static final NodeIdentifier ES_ROUTE_NID = new NodeIdentifier(EsRoute.QNAME); + private static final int CONTENT_LENGTH = 15; + private static final int CONTENT_LENGTH2 = 27; + + @Override + public EvpnChoice parseEvpn(final ByteBuf buffer) { + Preconditions.checkArgument(buffer.readableBytes() == CONTENT_LENGTH || buffer.readableBytes() == CONTENT_LENGTH2, + "Wrong length of array of bytes. Passed: %s ;", buffer); + + final Esi esi = SimpleEsiTypeRegistry.getInstance().parseEsi(buffer.readSlice(ESI_SIZE)); + final IpAddress ip = Preconditions.checkNotNull(parseOrigRouteIp(buffer)); + + final EsRouteBuilder builder = new EsRouteBuilder().setEsi(esi).setOrigRouteIp(ip); + return new EsRouteCaseBuilder().setEsRoute(builder.build()).build(); + } + + @Override + protected NlriType getType() { + return NlriType.EthSeg; + } + + @Override + public ByteBuf serializeBody(final EvpnChoice evpnInput) { + Preconditions.checkArgument(evpnInput instanceof EsRouteCase, "Unknown evpn instance. Passed %s. Needed EsRouteCase.", + evpnInput.getClass()); + return serializeBody(((EsRouteCase) evpnInput).getEsRoute()); + } + + @Override + public EvpnChoice serializeEvpnModel(final ContainerNode evpnCase) { + return createRouteKey(evpnCase); + } + + @Override + public EvpnChoice createRouteKey(final ContainerNode evpn) { + final EsRouteBuilder builder = new EsRouteBuilder(); + builder.setEsi(serializeEsi(evpn)); + builder.setOrigRouteIp(extractOrigRouteIp(evpn)); + return new EsRouteCaseBuilder().setEsRoute(builder.build()).build(); + } + + private static ByteBuf serializeBody(final EsRoute evpn) { + final ByteBuf body = Unpooled.buffer(); + SimpleEsiTypeRegistry.getInstance().serializeEsi(evpn.getEsi(), body); + final ByteBuf orig = serializeOrigRouteIp(evpn.getOrigRouteIp()); + Preconditions.checkArgument(orig.readableBytes() > 0); + body.writeBytes(orig); + return body; + } + + public static IpAddress parseOrigRouteIp(final ByteBuf buffer) { + final int ipLength = buffer.readByte(); + if (ipLength == Ipv6Util.IPV6_LENGTH) { + return new IpAddress(Ipv6Util.addressForByteBuf(buffer)); + } else if (ipLength == Ipv4Util.IP4_LENGTH) { + return new IpAddress(Ipv4Util.addressForByteBuf(buffer)); + } + return null; + } + + static ByteBuf serializeOrigRouteIp(final IpAddress origRouteIp) { + final ByteBuf body = Unpooled.buffer(); + if (origRouteIp.getIpv4Address() != null) { + body.writeByte(Ipv4Util.IP4_LENGTH); + body.writeBytes(Ipv4Util.bytesForAddress(origRouteIp.getIpv4Address())); + } else if (origRouteIp.getIpv6Address() != null) { + body.writeByte(Ipv6Util.IPV6_LENGTH); + body.writeBytes(Ipv6Util.bytesForAddress(origRouteIp.getIpv6Address())); + } else { + body.writeZero(ZERO_BYTE); + } + return body; + } +} diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EvpnNlriParser.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EvpnNlriParser.java new file mode 100644 index 0000000000..5dc0d0cff4 --- /dev/null +++ b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EvpnNlriParser.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.protocol.bgp.evpn.impl.nlri; + +import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.parseRouteDistinguisher; +import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.serializeRouteDistinquisher; +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractRouteDistinguisher; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nullable; +import org.opendaylight.protocol.bgp.evpn.spi.EvpnRegistry; +import org.opendaylight.protocol.bgp.evpn.spi.pojo.SimpleEvpnNlriRegistry; +import org.opendaylight.protocol.bgp.parser.BGPParsingException; +import org.opendaylight.protocol.bgp.parser.spi.NlriParser; +import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.NlriType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.EvpnChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.destination.EvpnDestination; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.destination.EvpnDestinationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationEvpnCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.evpn._case.DestinationEvpnBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class EvpnNlriParser implements NlriParser, NlriSerializer { + private static final Logger LOG = LoggerFactory.getLogger(EvpnNlriParser.class); + private static final NodeIdentifier EVPN_CHOICE_NID = new NodeIdentifier(EvpnChoice.QNAME); + + public static EvpnDestination extractEvpnDestination(final DataContainerNode evpnChoice) { + final EvpnRegistry reg = SimpleEvpnNlriRegistry.getInstance(); + final ChoiceNode choiceCont = (ChoiceNode) evpnChoice.getChild(EVPN_CHOICE_NID).get(); + final EvpnChoice evpnValue = reg.serializeEvpnModel(choiceCont); + if (evpnValue == null) { + LOG.warn("Unrecognized Nlri {}", choiceCont); + return null; + } + return new EvpnDestinationBuilder().setRouteDistinguisher(extractRouteDistinguisher(evpnChoice)).setEvpnChoice(evpnValue).build(); + } + + public static EvpnDestination extractRouteKeyDestination(final DataContainerNode evpnChoice) { + final EvpnRegistry reg = SimpleEvpnNlriRegistry.getInstance(); + final ChoiceNode choiceCont = (ChoiceNode) evpnChoice.getChild(EVPN_CHOICE_NID).get(); + final EvpnChoice evpnValue = reg.serializeEvpnRouteKey(choiceCont); + if (evpnValue == null) { + LOG.warn("Unrecognized Nlri {}", choiceCont); + return null; + } + return new EvpnDestinationBuilder().setRouteDistinguisher(extractRouteDistinguisher(evpnChoice)).setEvpnChoice(evpnValue).build(); + } + + @Override + public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder) throws BGPParsingException { + if (!nlri.isReadable()) { + return; + } + final List dst = parseNlri(nlri); + + builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn. + routes.destination.type.DestinationEvpnCaseBuilder().setDestinationEvpn(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns. + yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.evpn._case.DestinationEvpnBuilder() + .setEvpnDestination(dst).build()).build()).build()); + } + + @Override + public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder) throws BGPParsingException { + if (!nlri.isReadable()) { + return; + } + final List dst = parseNlri(nlri); + + builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType( + new DestinationEvpnCaseBuilder().setDestinationEvpn(new DestinationEvpnBuilder().setEvpnDestination(dst).build()).build()).build()); + } + + @Nullable + private List parseNlri(final ByteBuf nlri) { + if (!nlri.isReadable()) { + return null; + } + final List dests = new ArrayList<>(); + + while (nlri.isReadable()) { + final EvpnDestinationBuilder builder = new EvpnDestinationBuilder(); + final NlriType type = NlriType.forValue(nlri.readUnsignedByte()); + final int length = nlri.readUnsignedByte(); + final ByteBuf nlriBuf = nlri.readSlice(length); + builder.setRouteDistinguisher(parseRouteDistinguisher(nlriBuf)); + builder.setEvpnChoice(SimpleEvpnNlriRegistry.getInstance().parseEvpn(type, nlriBuf)); + dests.add(builder.build()); + } + return dests; + } + + @Override + public void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) { + Preconditions.checkArgument(attribute instanceof Attributes, "Attribute parameter is not a Attributes object"); + final Attributes pathAttributes = (Attributes) attribute; + final Attributes1 pathAttributes1 = pathAttributes.getAugmentation(Attributes1.class); + final Attributes2 pathAttributes2 = pathAttributes.getAugmentation(Attributes2.class); + if (pathAttributes1 != null) { + final AdvertizedRoutes routes = (pathAttributes1.getMpReachNlri()).getAdvertizedRoutes(); + if ((routes != null) && (routes.getDestinationType() instanceof DestinationEvpnCase)) { + final DestinationEvpnCase evpnCase = (DestinationEvpnCase) routes.getDestinationType(); + serializeNlri(evpnCase.getDestinationEvpn().getEvpnDestination(), byteAggregator); + } + } else if (pathAttributes2 != null) { + final MpUnreachNlri mpUnreachNlri = pathAttributes2.getMpUnreachNlri(); + final WithdrawnRoutes withdrawnRoutes = mpUnreachNlri.getWithdrawnRoutes(); + if (withdrawnRoutes != null && withdrawnRoutes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml + .ns.yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCase) { + final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn. + routes.destination.type.DestinationEvpnCase evpnCase = (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml + .ns.yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCase) mpUnreachNlri.getWithdrawnRoutes().getDestinationType(); + serializeNlri(evpnCase.getDestinationEvpn().getEvpnDestination(), byteAggregator); + } + } + } + + public static void serializeNlri(final List cEvpn, final ByteBuf output) { + ByteBuf nlriOutput = null; + for (final EvpnDestination dest : cEvpn) { + final ByteBuf nlriCommon = Unpooled.buffer(); + serializeRouteDistinquisher(dest.getRouteDistinguisher(), nlriCommon); + nlriOutput = SimpleEvpnNlriRegistry.getInstance().serializeEvpn(dest.getEvpnChoice(), nlriCommon); + } + output.writeBytes(nlriOutput); + } +} diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/IncMultEthTagRParser.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/IncMultEthTagRParser.java new file mode 100644 index 0000000000..a08b753659 --- /dev/null +++ b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/IncMultEthTagRParser.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.protocol.bgp.evpn.impl.nlri; + +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractETI; +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractOrigRouteIp; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.util.ByteBufWriteUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.NlriType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.tag.id.EthernetTagId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.tag.id.EthernetTagIdBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.EvpnChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.IncMultiEthernetTagResCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.IncMultiEthernetTagResCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.inc.multi.ethernet.tag.res.IncMultiEthernetTagRes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.inc.multi.ethernet.tag.res.IncMultiEthernetTagResBuilder; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; + +final class IncMultEthTagRParser extends AbstractEvpnNlri { + protected static final NodeIdentifier INC_MULT_ROUTE_NID = new NodeIdentifier(IncMultiEthernetTagRes.QNAME); + private static final int CONTENT_LENGTH = 9; + private static final int CONTENT_LENGTH2 = 21; + + @Override + public EvpnChoice parseEvpn(final ByteBuf buffer) { + Preconditions.checkArgument(buffer.readableBytes() == CONTENT_LENGTH || buffer.readableBytes() == CONTENT_LENGTH2, + "Wrong length of array of bytes. Passed: %s ;", buffer); + + final EthernetTagId eti = new EthernetTagIdBuilder().setVlanId(buffer.readUnsignedInt()).build(); + IpAddress ip = Preconditions.checkNotNull(EthSegRParser.parseOrigRouteIp(buffer)); + final IncMultiEthernetTagResBuilder builder = new IncMultiEthernetTagResBuilder().setEthernetTagId(eti).setOrigRouteIp(ip); + return new IncMultiEthernetTagResCaseBuilder().setIncMultiEthernetTagRes(builder.build()).build(); + } + + @Override + protected NlriType getType() { + return NlriType.IncMultEthTag; + } + + @Override + public ByteBuf serializeBody(final EvpnChoice evpn) { + Preconditions.checkArgument(evpn instanceof IncMultiEthernetTagResCase, "Unknown evpn instance. Passed %s. Needed IncMultiEthernetTagResCase.", + evpn.getClass()); + return serializeBody(((IncMultiEthernetTagResCase) evpn).getIncMultiEthernetTagRes()); + } + + @Override + public EvpnChoice serializeEvpnModel(final ContainerNode evpn) { + return createRouteKey(evpn); + } + + @Override + public EvpnChoice createRouteKey(final ContainerNode evpn) { + final IncMultiEthernetTagResBuilder builder = new IncMultiEthernetTagResBuilder(); + builder.setEthernetTagId(extractETI(evpn)); + builder.setOrigRouteIp(extractOrigRouteIp(evpn)); + return new IncMultiEthernetTagResCaseBuilder().setIncMultiEthernetTagRes(builder.build()).build(); + } + + private static ByteBuf serializeBody(final IncMultiEthernetTagRes evpn) { + final ByteBuf body = Unpooled.buffer(); + ByteBufWriteUtil.writeUnsignedInt(evpn.getEthernetTagId().getVlanId(), body); + final ByteBuf orig = EthSegRParser.serializeOrigRouteIp(evpn.getOrigRouteIp()); + Preconditions.checkArgument(orig.readableBytes() > 0); + body.writeBytes(orig); + return body; + } +} diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/MACIpAdvRParser.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/MACIpAdvRParser.java new file mode 100644 index 0000000000..062405f8b4 --- /dev/null +++ b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/MACIpAdvRParser.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.protocol.bgp.evpn.impl.nlri; + +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.MPLS1_NID; +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.MPLS2_NID; +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractETI; +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractIp; +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractMAC; +import static org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriModelUtil.extractMplsLabel; +import static org.opendaylight.protocol.util.MplsLabelUtil.byteBufForMplsLabel; +import static org.opendaylight.protocol.util.MplsLabelUtil.mplsLabelForByteBuf; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.opendaylight.protocol.bgp.evpn.spi.pojo.SimpleEsiTypeRegistry; +import org.opendaylight.protocol.util.ByteArray; +import org.opendaylight.protocol.util.ByteBufWriteUtil; +import org.opendaylight.protocol.util.Ipv4Util; +import org.opendaylight.protocol.util.Ipv6Util; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.IetfYangUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.NlriType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.esi.Esi; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.tag.id.EthernetTagId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.tag.id.EthernetTagIdBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.EvpnChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.MacIpAdvRouteCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.MacIpAdvRouteCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.mac.ip.adv.route.MacIpAdvRoute; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.mac.ip.adv.route.MacIpAdvRouteBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; + +final class MACIpAdvRParser extends AbstractEvpnNlri { + static final NodeIdentifier MAC_IP_ADV_ROUTE_NID = new NodeIdentifier(MacIpAdvRoute.QNAME); + private static final int BITS_SIZE = 8; + + @Override + public EvpnChoice parseEvpn(final ByteBuf buffer) { + final Esi esi = SimpleEsiTypeRegistry.getInstance().parseEsi(buffer.readSlice(ESI_SIZE)); + final EthernetTagId eti = new EthernetTagIdBuilder().setVlanId(buffer.readUnsignedInt()).build(); + buffer.skipBytes(1); + final MacAddress mac = IetfYangUtil.INSTANCE.macAddressFor(ByteArray.readBytes(buffer, MAC_ADDRESS_LENGTH)); + final IpAddress ip = parseIp(buffer); + final MplsLabel label1 = mplsLabelForByteBuf(buffer); + MplsLabel label2; + if (buffer.readableBytes() > 0) { + label2 = mplsLabelForByteBuf(buffer); + } else { + label2 = null; + } + final MacIpAdvRouteBuilder builder = new MacIpAdvRouteBuilder().setEsi(esi).setEthernetTagId(eti).setMacAddress(mac).setIpAddress(ip) + .setMplsLabel1(label1).setMplsLabel2(label2); + return new MacIpAdvRouteCaseBuilder().setMacIpAdvRoute(builder.build()).build(); + } + + @Override + protected NlriType getType() { + return NlriType.MacIpAdv; + } + + @Override + public ByteBuf serializeBody(final EvpnChoice evpn) { + Preconditions.checkArgument(evpn instanceof MacIpAdvRouteCase, "Unknown evpn instance. Passed %s. Needed MacIpAdvRouteCase.", evpn.getClass()); + return serializeBody((MacIpAdvRouteCase) evpn); + } + + @Override + public EvpnChoice serializeEvpnModel(final ContainerNode evpn) { + final MacIpAdvRouteBuilder builder = serializeKeyModel(evpn); + builder.setEsi(serializeEsi(evpn)); + builder.setMplsLabel1(extractMplsLabel(evpn, MPLS1_NID)); + builder.setMplsLabel2(extractMplsLabel(evpn, MPLS2_NID)); + return new MacIpAdvRouteCaseBuilder().setMacIpAdvRoute(builder.build()).build(); + } + + @Override + public EvpnChoice createRouteKey(final ContainerNode evpn) { + return new MacIpAdvRouteCaseBuilder().setMacIpAdvRoute(serializeKeyModel(evpn).build()).build(); + } + + private static MacIpAdvRouteBuilder serializeKeyModel(final ContainerNode evpn) { + final MacIpAdvRouteBuilder builder = new MacIpAdvRouteBuilder(); + builder.setEthernetTagId(extractETI(evpn)); + builder.setMacAddress(extractMAC(evpn)); + builder.setIpAddress(extractIp(evpn)); + return builder; + } + + private static ByteBuf serializeBody(final MacIpAdvRouteCase evpnCase) { + final ByteBuf body = Unpooled.buffer(); + final MacIpAdvRoute evpn = evpnCase.getMacIpAdvRoute(); + final Esi esi = evpn.getEsi(); + if (esi != null) { + SimpleEsiTypeRegistry.getInstance().serializeEsi(evpn.getEsi(), body); + } + ByteBufWriteUtil.writeUnsignedInt(evpn.getEthernetTagId().getVlanId(), body); + + final MacAddress mac = evpn.getMacAddress(); + body.writeByte(MAC_ADDRESS_LENGTH * BITS_SIZE); + body.writeBytes(IetfYangUtil.INSTANCE.bytesFor(mac)); + final ByteBuf ipAddress = serializeIp(evpn.getIpAddress()); + Preconditions.checkArgument(ipAddress.readableBytes() > 0); + body.writeBytes(ipAddress); + final MplsLabel mpls1 = evpn.getMplsLabel1(); + if (mpls1 != null) { + body.writeBytes(byteBufForMplsLabel(mpls1)); + } + final MplsLabel mpls2 = evpn.getMplsLabel2(); + if (mpls2 != null) { + body.writeBytes(byteBufForMplsLabel(mpls2)); + } + return body; + } + + private static ByteBuf serializeIp(final IpAddress ipAddress) { + final ByteBuf body = Unpooled.buffer(); + if (ipAddress.getIpv4Address() != null) { + body.writeByte(Ipv4Util.IP4_LENGTH * BITS_SIZE); + body.writeBytes(Ipv4Util.bytesForAddress(ipAddress.getIpv4Address())); + } else if (ipAddress.getIpv6Address() != null) { + body.writeByte(Ipv6Util.IPV6_LENGTH * BITS_SIZE); + body.writeBytes(Ipv6Util.bytesForAddress(ipAddress.getIpv6Address())); + } else { + body.writeZero(ZERO_BYTE); + } + return body; + } + + private static IpAddress parseIp(final ByteBuf buffer) { + final int ipLength = buffer.readUnsignedByte(); + if (ipLength == Ipv6Util.IPV6_LENGTH * BITS_SIZE) { + return new IpAddress(Ipv6Util.addressForByteBuf(buffer)); + } else if (ipLength == Ipv4Util.IP4_LENGTH * BITS_SIZE) { + return new IpAddress(Ipv4Util.addressForByteBuf(buffer)); + } + return null; + } +} diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/NlriActivator.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/NlriActivator.java new file mode 100644 index 0000000000..b24203333b --- /dev/null +++ b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/NlriActivator.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.protocol.bgp.evpn.impl.nlri; + +import java.util.List; +import org.opendaylight.protocol.bgp.evpn.spi.pojo.SimpleEvpnNlriRegistry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.es.route.EsRoute; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.a.d.route.EthernetADRoute; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.EsRouteCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.EthernetADRouteCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.IncMultiEthernetTagResCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.evpn.choice.MacIpAdvRouteCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.inc.multi.ethernet.tag.res.IncMultiEthernetTagRes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.mac.ip.adv.route.MacIpAdvRoute; + +public final class NlriActivator { + private NlriActivator() { + throw new UnsupportedOperationException(); + } + + public static void registerNlriParsers(final List regs) { + final SimpleEvpnNlriRegistry evpnNlriRegistry = SimpleEvpnNlriRegistry.getInstance(); + + final EthADRParser ethADR = new EthADRParser(); + regs.add(evpnNlriRegistry.registerNlriParser(ethADR.getType(), ethADR)); + regs.add(evpnNlriRegistry.registerNlriSerializer(EthernetADRouteCase.class, ethADR)); + regs.add(evpnNlriRegistry.registerNlriModelSerializer(EthernetADRoute.QNAME, ethADR)); + + final MACIpAdvRParser macIpAR = new MACIpAdvRParser(); + regs.add(evpnNlriRegistry.registerNlriParser(macIpAR.getType(), macIpAR)); + regs.add(evpnNlriRegistry.registerNlriSerializer(MacIpAdvRouteCase.class, macIpAR)); + regs.add(evpnNlriRegistry.registerNlriModelSerializer(MacIpAdvRoute.QNAME, macIpAR)); + + final IncMultEthTagRParser incMultETR = new IncMultEthTagRParser(); + regs.add(evpnNlriRegistry.registerNlriParser(incMultETR.getType(), incMultETR)); + regs.add(evpnNlriRegistry.registerNlriSerializer(IncMultiEthernetTagResCase.class, incMultETR)); + regs.add(evpnNlriRegistry.registerNlriModelSerializer(IncMultiEthernetTagRes.QNAME, incMultETR)); + + final EthSegRParser ethSR = new EthSegRParser(); + regs.add(evpnNlriRegistry.registerNlriParser(ethSR.getType(), ethSR)); + regs.add(evpnNlriRegistry.registerNlriSerializer(EsRouteCase.class, ethSR)); + regs.add(evpnNlriRegistry.registerNlriModelSerializer(EsRoute.QNAME, ethSR)); + } +} diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/NlriModelUtil.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/NlriModelUtil.java new file mode 100644 index 0000000000..3129951a52 --- /dev/null +++ b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/NlriModelUtil.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.protocol.bgp.evpn.impl.nlri; + +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.tag.id.EthernetTagId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.ethernet.tag.id.EthernetTagIdBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.EvpnChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisherBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode; + +final class NlriModelUtil { + static final NodeIdentifier ETI_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "ethernet-tag-id").intern()); + static final NodeIdentifier VLAN_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "vlan-id").intern()); + static final NodeIdentifier RD_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "route-distinguisher").intern()); + static final NodeIdentifier ORI_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "orig-route-ip").intern()); + static final NodeIdentifier MAC_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "mac-address").intern()); + static final NodeIdentifier IP_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "ip-address").intern()); + static final NodeIdentifier MPLS_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "mpls-label").intern()); + static final NodeIdentifier MPLS1_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "mpls-label1").intern()); + static final NodeIdentifier MPLS2_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "mpls-label2").intern()); + + private NlriModelUtil() { + throw new UnsupportedOperationException(); + } + + static RouteDistinguisher extractRouteDistinguisher(final DataContainerNode evpn) { + return RouteDistinguisherBuilder.getDefaultInstance((String) evpn.getChild(RD_NID).get().getValue()); + } + + static IpAddress extractOrigRouteIp(final DataContainerNode evpn) { + return IpAddressBuilder.getDefaultInstance((String) evpn.getChild(ORI_NID).get().getValue()); + } + + + static EthernetTagId extractETI(final ContainerNode evpn) { + final ContainerNode eti = (ContainerNode) evpn.getChild(ETI_NID).get(); + return new EthernetTagIdBuilder().setVlanId((Long) eti.getChild(VLAN_NID).get().getValue()).build(); + } + + static MacAddress extractMAC(final DataContainerNode evpn) { + return new MacAddress((String) evpn.getChild(MAC_NID).get().getValue()); + } + + + static IpAddress extractIp(final DataContainerNode evpn) { + if (evpn.getChild(IP_NID).isPresent()) { + return IpAddressBuilder.getDefaultInstance((String) evpn.getChild(IP_NID).get().getValue()); + } + return null; + } + + static MplsLabel extractMplsLabel(final DataContainerNode evpn, final NodeIdentifier mplsNid) { + if (evpn.getChild(mplsNid).isPresent()) { + return new MplsLabel((Long) evpn.getChild(mplsNid).get().getValue()); + } + return null; + } +} -- 2.36.6