<afi-safi>
<afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV6-UNICAST</afi-safi-name>
</afi-safi>
+ <afi-safi>
+ <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV4-MULTICAST</afi-safi-name>
+ </afi-safi>
+ <afi-safi>
+ <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV6-MULTICAST</afi-safi-name>
+ </afi-safi>
<afi-safi>
<afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L2VPN-EVPN</afi-safi-name>
</afi-safi>
<afi-safi>
<afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV6-UNICAST</afi-safi-name>
</afi-safi>
+ <afi-safi>
+ <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV4-MULTICAST</afi-safi-name>
+ </afi-safi>
+ <afi-safi>
+ <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV6-MULTICAST</afi-safi-name>
+ </afi-safi>
<afi-safi>
<afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L2VPN-EVPN</afi-safi-name>
</afi-safi>
<afi-safi>
<afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV6-UNICAST</afi-safi-name>
</afi-safi>
+ <afi-safi>
+ <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV4-MULTICAST</afi-safi-name>
+ </afi-safi>
+ <afi-safi>
+ <afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L3VPN-IPV6-MULTICAST</afi-safi-name>
+ </afi-safi>
<afi-safi>
<afi-safi-name xmlns:x="http://openconfig.net/yang/bgp-types">x:L2VPN-EVPN</afi-safi-name>
</afi-safi>
package org.opendaylight.protocol.bgp.l3vpn;
+import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.List;
+import org.opendaylight.protocol.bgp.inet.codec.nexthop.Ipv4NextHopParserSerializer;
+import org.opendaylight.protocol.bgp.inet.codec.nexthop.Ipv6NextHopParserSerializer;
+import org.opendaylight.protocol.bgp.l3vpn.mcast.nlri.L3vpnMcastIpv4NlriHandler;
+import org.opendaylight.protocol.bgp.l3vpn.mcast.nlri.L3vpnMcastIpv6NlriHandler;
import org.opendaylight.protocol.bgp.l3vpn.unicast.ipv4.VpnIpv4NextHopParserSerializer;
import org.opendaylight.protocol.bgp.l3vpn.unicast.ipv4.VpnIpv4NlriParser;
import org.opendaylight.protocol.bgp.l3vpn.unicast.ipv6.VpnIpv6NextHopParserSerializer;
import org.opendaylight.protocol.bgp.l3vpn.unicast.ipv6.VpnIpv6NlriParser;
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.l3vpn.mcast.rev180417.McastMplsLabeledVpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv4.L3vpnMcastRoutesIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv6.L3vpnMcastRoutesIpv6;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.MplsLabeledVpnSubsequentAddressFamily;
* @author Claudio D. Gasparini
*/
public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
+ @VisibleForTesting
+ static final int MCAST_L3VPN_SAFI = 129;
+
+
private static void registerNlri(
final BGPExtensionProviderContext context,
final List<AutoCloseable> regs) {
regs.add(context.registerNlriParser(Ipv6AddressFamily.class, MplsLabeledVpnSubsequentAddressFamily.class,
vpnIpv6NlriParser, vpnIpv6NextHopParserSerializer, Ipv6NextHopCase.class));
regs.add(context.registerNlriSerializer(VpnIpv6Routes.class, vpnIpv6NlriParser));
+
+ final L3vpnMcastIpv4NlriHandler l3vpnMcastIpv4NlriHandler = new L3vpnMcastIpv4NlriHandler();
+ final Ipv4NextHopParserSerializer ipv4NextHopParser = new Ipv4NextHopParserSerializer();
+ regs.add(context.registerNlriParser(Ipv4AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class,
+ l3vpnMcastIpv4NlriHandler, ipv4NextHopParser, Ipv4NextHopCase.class));
+ regs.add(context.registerNlriSerializer(L3vpnMcastRoutesIpv4.class, l3vpnMcastIpv4NlriHandler));
+
+
+ final L3vpnMcastIpv6NlriHandler l3vpnMcastIpv6NlriHandler = new L3vpnMcastIpv6NlriHandler();
+ final Ipv6NextHopParserSerializer ipv6NextHopParser = new Ipv6NextHopParserSerializer();
+ regs.add(context.registerNlriParser(Ipv6AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class,
+ l3vpnMcastIpv6NlriHandler, ipv6NextHopParser, Ipv6NextHopCase.class));
+ regs.add(context.registerNlriSerializer(L3vpnMcastRoutesIpv6.class, l3vpnMcastIpv6NlriHandler));
+ }
+
+ private static void registerAfiSafi(final BGPExtensionProviderContext context, final List<AutoCloseable> regs) {
+ regs.add(context.registerSubsequentAddressFamily(McastMplsLabeledVpnSubsequentAddressFamily.class,
+ MCAST_L3VPN_SAFI));
}
@Override
protected List<AutoCloseable> startImpl(final BGPExtensionProviderContext context) {
final List<AutoCloseable> regs = new ArrayList<>();
+ registerAfiSafi(context, regs);
registerNlri(context, regs);
return regs;
}
import com.google.common.collect.Lists;
import java.util.List;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.protocol.bgp.l3vpn.mcast.L3VpnMcastIpv4RIBSupport;
+import org.opendaylight.protocol.bgp.l3vpn.mcast.L3VpnMcastIpv6RIBSupport;
import org.opendaylight.protocol.bgp.l3vpn.unicast.ipv4.VpnIpv4RIBSupport;
import org.opendaylight.protocol.bgp.l3vpn.unicast.ipv6.VpnIpv6RIBSupport;
import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBExtensionProviderActivator;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.McastMplsLabeledVpnSubsequentAddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.MplsLabeledVpnSubsequentAddressFamily;
context.registerRIBSupport(Ipv4AddressFamily.class,
MplsLabeledVpnSubsequentAddressFamily.class, VpnIpv4RIBSupport.getInstance(mappingService)),
context.registerRIBSupport(Ipv6AddressFamily.class,
- MplsLabeledVpnSubsequentAddressFamily.class, VpnIpv6RIBSupport.getInstance(mappingService))
+ MplsLabeledVpnSubsequentAddressFamily.class, VpnIpv6RIBSupport.getInstance(mappingService)),
+ context.registerRIBSupport(Ipv4AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class,
+ L3VpnMcastIpv4RIBSupport.getInstance(mappingService)),
+ context.registerRIBSupport(Ipv6AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class,
+ L3VpnMcastIpv6RIBSupport.getInstance(mappingService))
);
}
}
import java.util.List;
import org.opendaylight.protocol.bgp.openconfig.spi.AbstractBGPTableTypeRegistryProviderActivator;
import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryProvider;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV4MULTICAST;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV4UNICAST;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV6MULTICAST;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV6UNICAST;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.McastMplsLabeledVpnSubsequentAddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.MplsLabeledVpnSubsequentAddressFamily;
provider.registerBGPTableType(Ipv4AddressFamily.class,
MplsLabeledVpnSubsequentAddressFamily.class, L3VPNIPV4UNICAST.class),
provider.registerBGPTableType(Ipv6AddressFamily.class,
- MplsLabeledVpnSubsequentAddressFamily.class, L3VPNIPV6UNICAST.class)
+ MplsLabeledVpnSubsequentAddressFamily.class, L3VPNIPV6UNICAST.class),
+ provider.registerBGPTableType(Ipv4AddressFamily.class,
+ McastMplsLabeledVpnSubsequentAddressFamily.class, L3VPNIPV4MULTICAST.class),
+ provider.registerBGPTableType(Ipv6AddressFamily.class,
+ McastMplsLabeledVpnSubsequentAddressFamily.class, L3VPNIPV6MULTICAST.class)
);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn.mcast;
+
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableSet;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
+import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.L3vpnMcastRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.McastMplsLabeledVpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.L3vpnMcastRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.L3vpnMcastRouteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.L3vpnMcastRouteKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.PathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.AddressFamily;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.ChoiceIn;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+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.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract L3VPN Multicast RIBSupport.
+ *
+ * @author Claudio D. Gasparini
+ */
+abstract class AbstractL3vpnMcastIpRIBSupport<
+ C extends Routes & DataObject & ChoiceIn<Tables>,
+ S extends ChildOf<? super C> & L3vpnMcastRoutes>
+ extends AbstractRIBSupport<C, S, L3vpnMcastRoute, L3vpnMcastRouteKey> {
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractL3vpnMcastIpRIBSupport.class);
+ private final NodeIdentifier nlriRoutesList;
+ private final NodeIdentifier rdNid;
+ private final ImmutableCollection<Class<? extends DataObject>> cacheableNlriObjects;
+
+ /**
+ * Default constructor. Requires the QName of the container augmented under the routes choice
+ * node in instantiations of the rib grouping. It is assumed that this container is defined by
+ * the same model which populates it with route grouping instantiation, and by extension with
+ * the route attributes container.
+ *
+ * @param mappingService Serialization service
+ * @param cazeClass Binding class of the AFI/SAFI-specific case statement, must not be null
+ * @param afiClass address Family Class
+ * @param destContainerQname destination container Qname
+ * @param destListQname destinations list Qname
+ */
+ AbstractL3vpnMcastIpRIBSupport(
+ final BindingNormalizedNodeSerializer mappingService,
+ final Class<C> cazeClass,
+ final Class<S> containerClass,
+ final Class<? extends AddressFamily> afiClass,
+ final QName destContainerQname,
+ final QName destListQname) {
+ super(mappingService, cazeClass, containerClass, L3vpnMcastRoute.class, afiClass,
+ McastMplsLabeledVpnSubsequentAddressFamily.class, destContainerQname);
+ final QNameModule module = BindingReflections.getQNameModule(cazeClass);
+ this.nlriRoutesList = NodeIdentifier.create(destListQname);
+ this.rdNid = new NodeIdentifier(QName.create(module, "route-distinguisher"));
+ this.cacheableNlriObjects = ImmutableSet.of(cazeClass);
+
+ }
+
+ @Override
+ public final ImmutableCollection<Class<? extends DataObject>> cacheableNlriObjects() {
+ return this.cacheableNlriObjects;
+ }
+
+ protected abstract IpPrefix createPrefix(String prefix);
+
+ @Override
+ public final L3vpnMcastRoute createRoute(final L3vpnMcastRoute route, final String routeKey, final long pathId,
+ final Attributes attributes) {
+ final L3vpnMcastRouteBuilder builder;
+ if (route != null) {
+ builder = new L3vpnMcastRouteBuilder(route);
+ } else {
+ builder = new L3vpnMcastRouteBuilder();
+ }
+ return builder.withKey(createRouteListKey(pathId, routeKey)).setAttributes(attributes).build();
+ }
+
+ @Override
+ public final L3vpnMcastRouteKey createRouteListKey(final long pathId, final String routeKey) {
+ return new L3vpnMcastRouteKey(new PathId(pathId), routeKey);
+ }
+
+ @Override
+ protected final void processDestination(
+ DOMDataWriteTransaction tx,
+ final YangInstanceIdentifier routesPath,
+ final ContainerNode destination,
+ final ContainerNode attributes,
+ final ApplyRoute function) {
+ if (destination != null) {
+ final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = destination
+ .getChild(nlriRoutesList);
+ if (maybeRoutes.isPresent()) {
+ final DataContainerChild<? extends PathArgument, ?> routes = maybeRoutes.get();
+ if (routes instanceof UnkeyedListNode) {
+ final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(routeNid());
+ for (final UnkeyedListEntryNode l3vpnDest : ((UnkeyedListNode) routes).getValue()) {
+ final YangInstanceIdentifier.NodeIdentifierWithPredicates routeKey = createRouteKey(l3vpnDest);
+ function.apply(tx, base, routeKey, l3vpnDest, attributes);
+ }
+ } else {
+ LOG.warn("Routes {} are not a map", routes);
+ }
+ }
+ }
+ }
+
+
+ final List<L3vpnMcastDestination> extractRoutes(final Collection<MapEntryNode> routes) {
+ return routes.stream().map(this::extractDestinations).collect(Collectors.toList());
+ }
+
+ final L3vpnMcastDestination extractDestinations(
+ final DataContainerNode<? extends PathArgument> destination) {
+ return new L3vpnMcastDestinationBuilder()
+ .setRouteDistinguisher(RouteDistinguisherUtil.extractRouteDistinguisher(destination, rdNid))
+ .setPrefix(createPrefix(extractPrefix(destination)))
+ .setPathId(PathIdUtil.buildPathId(destination, routePathIdNid()))
+ .build();
+ }
+
+ abstract NodeIdentifierWithPredicates createRouteKey(UnkeyedListEntryNode l3vpn);
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn.mcast;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Optional;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.protocol.bgp.l3vpn.mcast.nlri.L3vpnMcastNlriSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.bgp.rib.rib.loc.rib.tables.routes.L3vpnMcastRoutesIpv4Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.bgp.rib.rib.loc.rib.tables.routes.L3vpnMcastRoutesIpv4CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv4.L3vpnMcastRoutesIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv4.L3vpnMcastRoutesIpv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv4AdvertizedCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv4AdvertizedCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.l3vpn.mcast.ipv4.advertized._case.DestinationIpv4L3vpnMcast;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.l3vpn.mcast.ipv4.advertized._case.DestinationIpv4L3vpnMcastBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv4WithdrawnCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv4WithdrawnCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+
+/**
+ * Ipv4 L3VPN Multicast RIBSupport.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class L3VpnMcastIpv4RIBSupport
+ extends AbstractL3vpnMcastIpRIBSupport<L3vpnMcastRoutesIpv4Case, L3vpnMcastRoutesIpv4> {
+ private static final L3vpnMcastRoutesIpv4 EMPTY_CONTAINER
+ = new L3vpnMcastRoutesIpv4Builder().setL3vpnMcastRoute(Collections.emptyList()).build();
+ private static final L3vpnMcastRoutesIpv4Case EMPTY_CASE
+ = new L3vpnMcastRoutesIpv4CaseBuilder().setL3vpnMcastRoutesIpv4(EMPTY_CONTAINER).build();
+ private static L3VpnMcastIpv4RIBSupport SINGLETON;
+
+
+ private L3VpnMcastIpv4RIBSupport(final BindingNormalizedNodeSerializer mappingService) {
+ super(mappingService,
+ L3vpnMcastRoutesIpv4Case.class,
+ L3vpnMcastRoutesIpv4.class,
+ Ipv4AddressFamily.class,
+ DestinationIpv4L3vpnMcast.QNAME,
+ L3vpnMcastDestination.QNAME);
+ }
+
+ public static synchronized L3VpnMcastIpv4RIBSupport getInstance(
+ final BindingNormalizedNodeSerializer mappingService) {
+ if (SINGLETON == null) {
+ SINGLETON = new L3VpnMcastIpv4RIBSupport(mappingService);
+ }
+ return SINGLETON;
+ }
+
+
+ @Override
+ protected DestinationL3vpnMcastIpv4AdvertizedCase buildDestination(final Collection<MapEntryNode> routes) {
+ return new DestinationL3vpnMcastIpv4AdvertizedCaseBuilder().setDestinationIpv4L3vpnMcast(
+ new DestinationIpv4L3vpnMcastBuilder().setL3vpnMcastDestination(extractRoutes(routes)).build()).build();
+ }
+
+ @Override
+ protected DestinationL3vpnMcastIpv4WithdrawnCase buildWithdrawnDestination(final Collection<MapEntryNode> routes) {
+ return new DestinationL3vpnMcastIpv4WithdrawnCaseBuilder().setDestinationIpv4L3vpnMcast(
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update
+ .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.l3vpn.mcast.ipv4
+ .withdrawn._case.DestinationIpv4L3vpnMcastBuilder()
+ .setL3vpnMcastDestination(extractRoutes(routes)).build()).build();
+ }
+
+ @Override
+ public L3vpnMcastRoutesIpv4Case emptyRoutesCase() {
+ return EMPTY_CASE;
+ }
+
+ @Override
+ public L3vpnMcastRoutesIpv4 emptyRoutesContainer() {
+ return EMPTY_CONTAINER;
+ }
+
+ @Override
+ protected IpPrefix createPrefix(final String prefix) {
+ return new IpPrefix(new Ipv4Prefix(prefix));
+ }
+
+ @Override
+ public NodeIdentifierWithPredicates createRouteKey(final UnkeyedListEntryNode l3vpn) {
+ final ByteBuf buffer = Unpooled.buffer();
+ final L3vpnMcastDestination dest = extractDestinations(l3vpn);
+ L3vpnMcastNlriSerializer.serializeNlri(Collections.singletonList(dest), buffer);
+ final Optional<DataContainerChild<? extends PathArgument, ?>> maybePathIdLeaf =
+ l3vpn.getChild(routePathIdNid());
+ return PathIdUtil.createNidKey(routeQName(), routeKeyQName(),
+ pathIdQName(), ByteArray.encodeBase64(buffer), maybePathIdLeaf);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn.mcast;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Optional;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.protocol.bgp.l3vpn.mcast.nlri.L3vpnMcastNlriSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.bgp.rib.rib.loc.rib.tables.routes.L3vpnMcastRoutesIpv6Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.bgp.rib.rib.loc.rib.tables.routes.L3vpnMcastRoutesIpv6CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv6.L3vpnMcastRoutesIpv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv6.L3vpnMcastRoutesIpv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv6AdvertizedCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv6AdvertizedCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.l3vpn.mcast.ipv6.advertized._case.DestinationIpv6L3vpnMcast;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.l3vpn.mcast.ipv6.advertized._case.DestinationIpv6L3vpnMcastBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv6WithdrawnCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv6WithdrawnCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+
+/**
+ * Ipv6 L3VPN Multicast RIBSupport.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class L3VpnMcastIpv6RIBSupport
+ extends AbstractL3vpnMcastIpRIBSupport<L3vpnMcastRoutesIpv6Case, L3vpnMcastRoutesIpv6> {
+ private static final L3vpnMcastRoutesIpv6 EMPTY_CONTAINER
+ = new L3vpnMcastRoutesIpv6Builder().setL3vpnMcastRoute(Collections.emptyList()).build();
+ private static final L3vpnMcastRoutesIpv6Case EMPTY_CASE
+ = new L3vpnMcastRoutesIpv6CaseBuilder().setL3vpnMcastRoutesIpv6(EMPTY_CONTAINER).build();
+ private static L3VpnMcastIpv6RIBSupport SINGLETON;
+
+
+ private L3VpnMcastIpv6RIBSupport(final BindingNormalizedNodeSerializer mappingService) {
+ super(mappingService,
+ L3vpnMcastRoutesIpv6Case.class,
+ L3vpnMcastRoutesIpv6.class,
+ Ipv6AddressFamily.class,
+ DestinationIpv6L3vpnMcast.QNAME,
+ L3vpnMcastDestination.QNAME);
+ }
+
+ public static synchronized L3VpnMcastIpv6RIBSupport getInstance(
+ final BindingNormalizedNodeSerializer mappingService) {
+ if (SINGLETON == null) {
+ SINGLETON = new L3VpnMcastIpv6RIBSupport(mappingService);
+ }
+ return SINGLETON;
+ }
+
+
+ @Override
+ protected DestinationL3vpnMcastIpv6AdvertizedCase buildDestination(final Collection<MapEntryNode> routes) {
+ return new DestinationL3vpnMcastIpv6AdvertizedCaseBuilder().setDestinationIpv6L3vpnMcast(
+ new DestinationIpv6L3vpnMcastBuilder().setL3vpnMcastDestination(extractRoutes(routes)).build()).build();
+ }
+
+ @Override
+ protected DestinationL3vpnMcastIpv6WithdrawnCase buildWithdrawnDestination(final Collection<MapEntryNode> routes) {
+ return new DestinationL3vpnMcastIpv6WithdrawnCaseBuilder().setDestinationIpv6L3vpnMcast(
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update
+ .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.l3vpn.mcast.ipv6
+ .withdrawn._case.DestinationIpv6L3vpnMcastBuilder()
+ .setL3vpnMcastDestination(extractRoutes(routes)).build()).build();
+ }
+
+ @Override
+ public L3vpnMcastRoutesIpv6Case emptyRoutesCase() {
+ return EMPTY_CASE;
+ }
+
+ @Override
+ public L3vpnMcastRoutesIpv6 emptyRoutesContainer() {
+ return EMPTY_CONTAINER;
+ }
+
+ @Override
+ protected IpPrefix createPrefix(final String prefix) {
+ return new IpPrefix(new Ipv6Prefix(prefix));
+ }
+
+ @Override
+ public NodeIdentifierWithPredicates createRouteKey(final UnkeyedListEntryNode l3vpn) {
+ final ByteBuf buffer = Unpooled.buffer();
+ final L3vpnMcastDestination dest = extractDestinations(l3vpn);
+ L3vpnMcastNlriSerializer.serializeNlri(Collections.singletonList(dest), buffer);
+ final Optional<DataContainerChild<? extends PathArgument, ?>> maybePathIdLeaf =
+ l3vpn.getChild(routePathIdNid());
+ return PathIdUtil.createNidKey(routeQName(), routeKeyQName(),
+ pathIdQName(), ByteArray.encodeBase64(buffer), maybePathIdLeaf);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn.mcast.nlri;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
+import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupportUtil;
+import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
+import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv4AdvertizedCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv4AdvertizedCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.l3vpn.mcast.ipv4.advertized._case.DestinationIpv4L3vpnMcastBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv4WithdrawnCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv4WithdrawnCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * https://tools.ietf.org/html/rfc6514#section-4.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class L3vpnMcastIpv4NlriHandler implements NlriParser, NlriSerializer {
+ @Override
+ public void parseNlri(
+ final ByteBuf nlri,
+ final MpReachNlriBuilder builder,
+ final PeerSpecificParserConstraint constraint) throws BGPParsingException {
+ if (!nlri.isReadable()) {
+ return;
+ }
+ final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint,
+ new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
+ builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder()
+ .setDestinationType(new DestinationL3vpnMcastIpv4AdvertizedCaseBuilder()
+ .setDestinationIpv4L3vpnMcast(new DestinationIpv4L3vpnMcastBuilder()
+ .setL3vpnMcastDestination(L3vpnMcastNlriSerializer.extractDest(nlri, mPathSupported))
+ .build()).build()).build());
+ }
+
+
+ @Override
+ public void parseNlri(
+ final ByteBuf nlri,
+ final MpUnreachNlriBuilder builder,
+ final PeerSpecificParserConstraint constraint) throws BGPParsingException {
+ if (!nlri.isReadable()) {
+ return;
+ }
+ final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint,
+ new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
+ builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder()
+ .setDestinationType(new DestinationL3vpnMcastIpv4WithdrawnCaseBuilder().setDestinationIpv4L3vpnMcast(
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417
+ .update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.l3vpn
+ .mcast.ipv4.withdrawn._case.DestinationIpv4L3vpnMcastBuilder()
+ .setL3vpnMcastDestination(L3vpnMcastNlriSerializer.extractDest(nlri, mPathSupported))
+ .build()).build()).build());
+ }
+
+ @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.augmentation(Attributes1.class);
+ final Attributes2 pathAttributes2 = pathAttributes.augmentation(Attributes2.class);
+ if (pathAttributes1 != null) {
+ final AdvertizedRoutes routes = pathAttributes1.getMpReachNlri().getAdvertizedRoutes();
+ if (routes != null && routes.getDestinationType() instanceof DestinationL3vpnMcastIpv4AdvertizedCase) {
+ final DestinationL3vpnMcastIpv4AdvertizedCase reach
+ = (DestinationL3vpnMcastIpv4AdvertizedCase) routes.getDestinationType();
+ L3vpnMcastNlriSerializer.serializeNlri(reach.getDestinationIpv4L3vpnMcast().getL3vpnMcastDestination(),
+ byteAggregator);
+ }
+ } else if (pathAttributes2 != null) {
+ final WithdrawnRoutes withdrawnRoutes = pathAttributes2.getMpUnreachNlri().getWithdrawnRoutes();
+ if (withdrawnRoutes != null
+ && withdrawnRoutes.getDestinationType() instanceof DestinationL3vpnMcastIpv4WithdrawnCase) {
+ final DestinationL3vpnMcastIpv4WithdrawnCase reach
+ = (DestinationL3vpnMcastIpv4WithdrawnCase) withdrawnRoutes.getDestinationType();
+ L3vpnMcastNlriSerializer.serializeNlri(reach.getDestinationIpv4L3vpnMcast().getL3vpnMcastDestination(),
+ byteAggregator);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn.mcast.nlri;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
+import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupportUtil;
+import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
+import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv6AdvertizedCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv6AdvertizedCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.l3vpn.mcast.ipv6.advertized._case.DestinationIpv6L3vpnMcastBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv6WithdrawnCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv6WithdrawnCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * https://tools.ietf.org/html/rfc6514#section-4.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class L3vpnMcastIpv6NlriHandler implements NlriParser, NlriSerializer {
+ @Override
+ public void parseNlri(
+ final ByteBuf nlri,
+ final MpReachNlriBuilder builder,
+ final PeerSpecificParserConstraint constraint) throws BGPParsingException {
+ if (!nlri.isReadable()) {
+ return;
+ }
+ final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint,
+ new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
+
+ builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
+ new DestinationL3vpnMcastIpv6AdvertizedCaseBuilder().setDestinationIpv6L3vpnMcast(
+ new DestinationIpv6L3vpnMcastBuilder().setL3vpnMcastDestination(
+ L3vpnMcastNlriSerializer.extractDest(nlri, mPathSupported)).build()).build()).build());
+ }
+
+
+ @Override
+ public void parseNlri(
+ final ByteBuf nlri,
+ final MpUnreachNlriBuilder builder,
+ final PeerSpecificParserConstraint constraint) throws BGPParsingException {
+ if (!nlri.isReadable()) {
+ return;
+ }
+ final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint,
+ new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
+ builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder()
+ .setDestinationType(new DestinationL3vpnMcastIpv6WithdrawnCaseBuilder().setDestinationIpv6L3vpnMcast(
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417
+ .update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.l3vpn
+ .mcast.ipv6.withdrawn._case.DestinationIpv6L3vpnMcastBuilder()
+ .setL3vpnMcastDestination(L3vpnMcastNlriSerializer.extractDest(nlri, mPathSupported))
+ .build()).build()).build());
+ }
+
+ @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.augmentation(Attributes1.class);
+ final Attributes2 pathAttributes2 = pathAttributes.augmentation(Attributes2.class);
+ if (pathAttributes1 != null) {
+ final AdvertizedRoutes routes = pathAttributes1.getMpReachNlri().getAdvertizedRoutes();
+ if (routes != null && routes.getDestinationType() instanceof DestinationL3vpnMcastIpv6AdvertizedCase) {
+ final DestinationL3vpnMcastIpv6AdvertizedCase reach
+ = (DestinationL3vpnMcastIpv6AdvertizedCase) routes.getDestinationType();
+ L3vpnMcastNlriSerializer.serializeNlri(reach.getDestinationIpv6L3vpnMcast().getL3vpnMcastDestination(),
+ byteAggregator);
+ }
+ } else if (pathAttributes2 != null) {
+ final WithdrawnRoutes withdrawnRoutes = pathAttributes2.getMpUnreachNlri().getWithdrawnRoutes();
+ if (withdrawnRoutes != null
+ && withdrawnRoutes.getDestinationType() instanceof DestinationL3vpnMcastIpv6WithdrawnCase) {
+ final DestinationL3vpnMcastIpv6WithdrawnCase reach
+ = (DestinationL3vpnMcastIpv6WithdrawnCase) withdrawnRoutes.getDestinationType();
+ L3vpnMcastNlriSerializer.serializeNlri(reach.getDestinationIpv6L3vpnMcast().getL3vpnMcastDestination(),
+ byteAggregator);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn.mcast.nlri;
+
+import static org.opendaylight.protocol.util.Ipv6Util.IPV6_LENGTH;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
+import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
+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.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestinationBuilder;
+
+public final class L3vpnMcastNlriSerializer {
+ private L3vpnMcastNlriSerializer() {
+ throw new UnsupportedOperationException();
+ }
+
+ static List<L3vpnMcastDestination> extractDest(final ByteBuf nlri, final boolean addPath) {
+ List<L3vpnMcastDestination> dests = new ArrayList<>();
+ while (nlri.isReadable()) {
+ final L3vpnMcastDestinationBuilder builder = new L3vpnMcastDestinationBuilder();
+ if (addPath) {
+ builder.setPathId(PathIdUtil.readPathId(nlri));
+ }
+ final int length = nlri.readUnsignedByte();
+ builder.setRouteDistinguisher(RouteDistinguisherUtil.parseRouteDistinguisher(nlri));
+ if (length == IPV6_LENGTH) {
+ builder.setPrefix(new IpPrefix(Ipv6Util.prefixForByteBuf(nlri)));
+ } else {
+ builder.setPrefix(new IpPrefix(Ipv4Util.prefixForByteBuf(nlri)));
+ }
+ dests.add(builder.build());
+ }
+ return dests;
+ }
+
+ public static void serializeNlri(final List<L3vpnMcastDestination> destinationList, final ByteBuf output) {
+ for (final L3vpnMcastDestination dest : destinationList) {
+ PathIdUtil.writePathId(dest.getPathId(), output);
+ ByteBuf nlriOutput = Unpooled.buffer();
+ RouteDistinguisherUtil.serializeRouteDistinquisher(dest.getRouteDistinguisher(), nlriOutput);
+ final IpPrefix prefix = dest.getPrefix();
+ if (prefix.getIpv4Prefix() != null) {
+ output.writeByte(Ipv4Util.IP4_BITS_LENGTH);
+ nlriOutput.writeBytes(Ipv4Util.bytesForPrefix(prefix.getIpv4Prefix()));
+ } else {
+ output.writeByte(Ipv6Util.IPV6_BITS_LENGTH);
+ nlriOutput.writeBytes(Ipv6Util.bytesForPrefix(prefix.getIpv6Prefix()));
+ }
+ while (nlriOutput.readableBytes() % 8 != 0) {
+ nlriOutput.writeZero(1);
+ }
+ output.writeBytes(nlriOutput);
+ }
+ }
+}
--- /dev/null
+module bgp-l3vpn-mcast {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:bgp:l3vpn:mcast";
+ prefix "bgp-l3vpn-mcast";
+
+ import bgp-rib { prefix bgp-rib; revision-date 2018-03-29; }
+ import bgp-multiprotocol { prefix bgp-mp; revision-date 2018-03-29; }
+ import ietf-inet-types { prefix inet; revision-date 2013-07-15; }
+ import bgp-message { prefix bgp-msg; revision-date 2018-03-29; }
+ import bmp-monitor { prefix bmp-mon; revision-date 2018-03-29; }
+ import bgp-types { prefix bgp-t; revision-date 2018-03-29; }
+
+ organization "AT&T Services, Inc.";
+
+ contact "Claudio D. Gasparini <claudio.gasparini@pantheon.tech>";
+
+ description
+ "This module contains the base data model of a BGP message.
+ It rolls up the definitions contained in RFC6513, RFC6514.
+
+ Copyright (c) 2018 AT&T Intellectual Property. 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";
+
+ revision 2018-04-17 {
+ description "Initial version";
+ }
+
+ identity mcast-mpls-labeled-vpn-subsequent-address-family {
+ description "SAFI 129 multicast l3vpn";
+ reference "https://www.iana.org/assignments/safi-namespace/safi-namespace.xhtml";
+
+ base bgp-t:subsequent-address-family;
+ }
+
+ grouping l3vpn-mcast-route {
+ leaf prefix {
+ type inet:ip-prefix;
+ }
+ uses bgp-t:route-distinguisher-grouping;
+ }
+
+ grouping l3vpn-mcast-destination {
+ list l3vpn-mcast-destination {
+ uses l3vpn-mcast-route;
+ uses bgp-msg:path-id-grouping;
+ }
+ }
+
+ grouping l3vpn-mcast-routes {
+ list l3vpn-mcast-route {
+ key "route-key path-id";
+ uses bgp-rib:route;
+ uses l3vpn-mcast-route;
+ }
+ }
+
+ grouping l3vpn-mcast-routes-ipv4 {
+ container l3vpn-mcast-routes-ipv4 {
+ uses l3vpn-mcast-routes;
+ }
+ }
+
+ grouping l3vpn-mcast-routes-ipv6 {
+ container l3vpn-mcast-routes-ipv6 {
+ uses l3vpn-mcast-routes;
+ }
+ }
+
+ augment "/bgp-msg:update/bgp-msg:attributes/bgp-mp:mp-reach-nlri/bgp-mp:advertized-routes/bgp-mp:destination-type" {
+ case destination-l3vpn-mcast-ipv4-advertized-case {
+ when "../../afi = ipv4";
+ container destination-ipv4-l3vpn-mcast {
+ uses l3vpn-mcast-destination;
+ }
+ }
+ case destination-l3vpn-mcast-ipv6-advertized-case {
+ when "../../afi = ipv6";
+ container destination-ipv6-l3vpn-mcast {
+ uses l3vpn-mcast-destination;
+ }
+ }
+ }
+
+ augment "/bgp-msg:update/bgp-msg:attributes/bgp-mp:mp-unreach-nlri/bgp-mp:withdrawn-routes/bgp-mp:destination-type" {
+ case destination-l3vpn-mcast-ipv4-withdrawn-case {
+ when "../../afi = ipv4";
+ container destination-ipv4-l3vpn-mcast {
+ uses l3vpn-mcast-destination;
+ }
+ }
+ case destination-l3vpn-mcast-ipv6-withdrawn-case {
+ when "../../afi = ipv6";
+ container destination-ipv6-l3vpn-mcast {
+ uses l3vpn-mcast-destination;
+ }
+ }
+ }
+
+ augment "/bgp-rib:application-rib/bgp-rib:tables/bgp-rib:routes" {
+ case l3vpn-mcast-routes-ipv4-case {
+ uses l3vpn-mcast-routes-ipv4;
+ }
+
+ case l3vpn-mcast-routes-ipv6-case {
+ uses l3vpn-mcast-routes-ipv6;
+ }
+ }
+
+ augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:loc-rib/bgp-rib:tables/bgp-rib:routes" {
+ case l3vpn-mcast-routes-ipv4-case {
+ uses l3vpn-mcast-routes-ipv4;
+ }
+
+ case l3vpn-mcast-routes-ipv6-case {
+ uses l3vpn-mcast-routes-ipv6;
+ }
+ }
+
+ augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:peer/bgp-rib:adj-rib-in/bgp-rib:tables/bgp-rib:routes" {
+ case l3vpn-mcast-routes-ipv4-case {
+ uses l3vpn-mcast-routes-ipv4;
+ }
+
+ case l3vpn-mcast-routes-ipv6-case {
+ uses l3vpn-mcast-routes-ipv6;
+ }
+ }
+
+ augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:peer/bgp-rib:effective-rib-in/bgp-rib:tables/bgp-rib:routes" {
+ case l3vpn-mcast-routes-ipv4-case {
+ uses l3vpn-mcast-routes-ipv4;
+ }
+
+ case l3vpn-mcast-routes-ipv6-case {
+ uses l3vpn-mcast-routes-ipv6;
+ }
+ }
+
+ augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:peer/bgp-rib:adj-rib-out/bgp-rib:tables/bgp-rib:routes" {
+ case l3vpn-mcast-routes-ipv4-case {
+ uses l3vpn-mcast-routes-ipv4;
+ }
+
+ case l3vpn-mcast-routes-ipv6-case {
+ uses l3vpn-mcast-routes-ipv6;
+ }
+ }
+
+ augment "/bmp-mon:bmp-monitor/bmp-mon:monitor/bmp-mon:router/bmp-mon:peer/bmp-mon:pre-policy-rib/bmp-mon:tables/bmp-mon:routes" {
+ case l3vpn-mcast-routes-ipv4-case {
+ uses l3vpn-mcast-routes-ipv4;
+ }
+
+ case l3vpn-mcast-routes-ipv6-case {
+ uses l3vpn-mcast-routes-ipv6;
+ }
+ }
+
+ augment "/bmp-mon:bmp-monitor/bmp-mon:monitor/bmp-mon:router/bmp-mon:peer/bmp-mon:post-policy-rib/bmp-mon:tables/bmp-mon:routes" {
+ case l3vpn-mcast-routes-ipv4-case {
+ uses l3vpn-mcast-routes-ipv4;
+ }
+
+ case l3vpn-mcast-routes-ipv6-case {
+ uses l3vpn-mcast-routes-ipv6;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
+import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.McastMplsLabeledVpnSubsequentAddressFamily;
+
+public final class BGPActivatorTest {
+ @Test
+ public void testActivator() {
+ final BGPActivator act = new BGPActivator();
+ final BGPExtensionProviderContext context = new SimpleBGPExtensionProviderContext();
+ assertNull(context.getSubsequentAddressFamilyRegistry().classForFamily(BGPActivator.MCAST_L3VPN_SAFI));
+ act.start(context);
+ assertEquals(McastMplsLabeledVpnSubsequentAddressFamily.class, context.getSubsequentAddressFamilyRegistry()
+ .classForFamily(BGPActivator.MCAST_L3VPN_SAFI));
+ act.close();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBActivatorTest;
+import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
+import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.McastMplsLabeledVpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
+
+public class RIBActivatorTest extends AbstractRIBActivatorTest {
+ @Test
+ public void testRIBActivator() {
+ final RIBActivator ribAct = new RIBActivator();
+ final RIBExtensionProviderContext context = new SimpleRIBExtensionProviderContext();
+ assertNull(context.getRIBSupport(Ipv4AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class));
+ assertNull(context.getRIBSupport(Ipv6AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class));
+ ribAct.startRIBExtensionProvider(context, this.mappingService);
+ assertNotNull(context.getRIBSupport(Ipv4AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class));
+ assertNotNull(context.getRIBSupport(Ipv6AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class));
+ ribAct.close();
+ }
+}
\ No newline at end of file
import org.opendaylight.protocol.bgp.openconfig.spi.SimpleBGPTableTypeRegistryProvider;
import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV4MULTICAST;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV4UNICAST;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV6MULTICAST;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV6UNICAST;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.McastMplsLabeledVpnSubsequentAddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
private static final BgpTableType IPV6 = new BgpTableTypeImpl(Ipv6AddressFamily.class,
MplsLabeledVpnSubsequentAddressFamily.class);
+ private static final BgpTableType MCAST_L3VPN_IPV4 = new BgpTableTypeImpl(
+ Ipv4AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class);
+ private static final BgpTableType MCAST_L3VPN_IPV6 = new BgpTableTypeImpl(
+ Ipv6AddressFamily.class, McastMplsLabeledVpnSubsequentAddressFamily.class);
+
@Test
public void testActivator() {
final TableTypeActivator tableTypeActivator = new TableTypeActivator();
final Optional<BgpTableType> tableType2 = registry.getTableType(L3VPNIPV6UNICAST.class);
Assert.assertEquals(IPV6, tableType2.get());
+ final Optional<Class<? extends AfiSafiType>> afiSafiType4 = registry.getAfiSafiType(MCAST_L3VPN_IPV4);
+ Assert.assertEquals(L3VPNIPV4MULTICAST.class, afiSafiType4.get());
+ final Optional<Class<? extends AfiSafiType>> afiSafiType6 = registry.getAfiSafiType(MCAST_L3VPN_IPV6);
+ Assert.assertEquals(L3VPNIPV6MULTICAST.class, afiSafiType6.get());
+
+ final Optional<BgpTableType> tableType4 = registry.getTableType(L3VPNIPV4MULTICAST.class);
+ Assert.assertEquals(MCAST_L3VPN_IPV4, tableType4.get());
+ final Optional<BgpTableType> tableType6 = registry.getTableType(L3VPNIPV6MULTICAST.class);
+ Assert.assertEquals(MCAST_L3VPN_IPV6, tableType6.get());
+
tableTypeActivator.stopBGPTableTypeRegistryProvider();
tableTypeActivator.close();
}
-
}
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn.mcast;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Collection;
+import java.util.Collections;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupportTest;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.bgp.rib.rib.loc.rib.tables.routes.L3vpnMcastRoutesIpv4Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.bgp.rib.rib.loc.rib.tables.routes.L3vpnMcastRoutesIpv4CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.L3vpnMcastRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.L3vpnMcastRouteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.L3vpnMcastRouteKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv4.L3vpnMcastRoutesIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv4.L3vpnMcastRoutesIpv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv4AdvertizedCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv4AdvertizedCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.l3vpn.mcast.ipv4.advertized._case.DestinationIpv4L3vpnMcastBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv4WithdrawnCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv4WithdrawnCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.PathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.Update;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
+
+public class L3vpnMcastIpv4RIBSupportTest extends AbstractRIBSupportTest<L3vpnMcastRoutesIpv4Case ,L3vpnMcastRoutesIpv4,
+ L3vpnMcastRoute, L3vpnMcastRouteKey> {
+ private static final PathId PATH_ID = new PathId(0L);
+ private static final IpPrefix IPV4_PREFIX = new IpPrefix(new Ipv4Prefix("34.1.22.0/24"));
+ private static final RouteDistinguisher RD = new RouteDistinguisher(new RdIpv4("1.2.3.4:258"));
+ private static final L3vpnMcastRouteKey ROUTE_KEY
+ = new L3vpnMcastRouteKey(PATH_ID, "IAABAQIDBAECIgEWABgAAAA=");
+ private static final L3vpnMcastRoute ROUTE = new L3vpnMcastRouteBuilder()
+ .setRouteKey(ROUTE_KEY.getRouteKey())
+ .setPathId(ROUTE_KEY.getPathId())
+ .setAttributes(ATTRIBUTES)
+ .setRouteDistinguisher(RD)
+ .setPrefix(IPV4_PREFIX)
+ .build();
+ private static final L3vpnMcastRoutesIpv4 MCAST_L3VPN_ROUTES
+ = new L3vpnMcastRoutesIpv4Builder().setL3vpnMcastRoute(Collections.singletonList(ROUTE)).build();
+
+ private static final L3vpnMcastDestination MCAST_L3VPN_DESTINATION = new L3vpnMcastDestinationBuilder()
+ .setRouteDistinguisher(RD)
+ .setPrefix(IPV4_PREFIX)
+ .setPathId(PATH_ID)
+ .build();
+ private static final DestinationL3vpnMcastIpv4AdvertizedCase REACH_NLRI
+ = new DestinationL3vpnMcastIpv4AdvertizedCaseBuilder()
+ .setDestinationIpv4L3vpnMcast(new DestinationIpv4L3vpnMcastBuilder()
+ .setL3vpnMcastDestination(Collections.singletonList(MCAST_L3VPN_DESTINATION)).build()).build();
+ private static final DestinationL3vpnMcastIpv4WithdrawnCase UNREACH_NLRI
+ = new DestinationL3vpnMcastIpv4WithdrawnCaseBuilder()
+ .setDestinationIpv4L3vpnMcast(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp
+ .l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
+ .destination.l3vpn.mcast.ipv4.withdrawn._case.DestinationIpv4L3vpnMcastBuilder()
+ .setL3vpnMcastDestination(Collections.singletonList(MCAST_L3VPN_DESTINATION)).build()).build();
+
+ private L3VpnMcastIpv4RIBSupport ribSupport;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ ribSupport = L3VpnMcastIpv4RIBSupport.getInstance(this.mappingService);
+ setUpTestCustomizer(ribSupport);
+ }
+
+ @Test
+ public void testDeleteRoutes() {
+ final ContainerNode withdraw = createNlriWithDrawnRoute(UNREACH_NLRI);
+ this.ribSupport.deleteRoutes(this.tx, getTablePath(), withdraw);
+ final InstanceIdentifier<L3vpnMcastRoute> instanceIdentifier = this.deletedRoutes.get(0);
+ assertEquals(ROUTE_KEY, instanceIdentifier.firstKeyOf(L3vpnMcastRoute.class));
+ }
+
+ @Test
+ public void testPutRoutes() {
+ this.ribSupport.putRoutes(this.tx, getTablePath(), createNlriAdvertiseRoute(REACH_NLRI), createAttributes());
+ final L3vpnMcastRoute route = (L3vpnMcastRoute) this.insertedRoutes.get(0).getValue();
+ assertEquals(ROUTE, route);
+ }
+
+
+ @Test
+ public void testEmptyRoute() {
+ final Routes empty = new L3vpnMcastRoutesIpv4CaseBuilder()
+ .setL3vpnMcastRoutesIpv4(new L3vpnMcastRoutesIpv4Builder()
+ .setL3vpnMcastRoute(Collections.emptyList()).build()).build();
+ final ChoiceNode expected = createRoutes(empty);
+ Assert.assertEquals(expected, this.ribSupport.emptyRoutes());
+ }
+
+ @Test
+ public void testBuildMpUnreachNlriUpdate() {
+ final Collection<MapEntryNode> routes = createRoutes(MCAST_L3VPN_ROUTES);
+ final Update update = this.ribSupport.buildUpdate(Collections.emptyList(), routes, ATTRIBUTES);
+ assertEquals(UNREACH_NLRI, update.getAttributes().augmentation(Attributes2.class).getMpUnreachNlri()
+ .getWithdrawnRoutes().getDestinationType());
+ assertNull(update.getAttributes().augmentation(Attributes1.class));
+ }
+
+ @Test
+ public void testBuildMpReachNlriUpdate() {
+ final Collection<MapEntryNode> routes = createRoutes(MCAST_L3VPN_ROUTES);
+ final Update update = this.ribSupport.buildUpdate(routes, Collections.emptyList(), ATTRIBUTES);
+ assertEquals(REACH_NLRI, update.getAttributes().augmentation(Attributes1.class).getMpReachNlri()
+ .getAdvertizedRoutes().getDestinationType());
+ assertNull(update.getAttributes().augmentation(Attributes2.class));
+ }
+
+ @Test
+ public void testCacheableNlriObjects() {
+ Assert.assertEquals(ImmutableSet.of(L3vpnMcastRoutesIpv4Case.class), this.ribSupport.cacheableNlriObjects());
+ }
+
+ @Test
+ public void testCacheableAttributeObjects() {
+ Assert.assertEquals(ImmutableSet.of(), this.ribSupport.cacheableAttributeObjects());
+ }
+
+ @Test
+ public void testRouteIdAddPath() {
+ Assert.assertEquals(ROUTE_KEY, this.ribSupport.createRouteListKey(ROUTE_KEY.getPathId().getValue(),
+ ROUTE_KEY.getRouteKey()));
+ }
+
+ @Test
+ public void testRoutePath() {
+ final YangInstanceIdentifier.NodeIdentifierWithPredicates prefixNii = createRouteNIWP(MCAST_L3VPN_ROUTES);
+ final YangInstanceIdentifier expected = getRoutePath().node(prefixNii);
+ final YangInstanceIdentifier actual = this.ribSupport.routePath(getTablePath().node(Routes.QNAME), prefixNii);
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testRouteAttributesIdentifier() {
+ Assert.assertEquals(new YangInstanceIdentifier.NodeIdentifier(
+ Attributes.QNAME.withModule(BindingReflections.getQNameModule(L3vpnMcastRoutesIpv4Case.class))),
+ this.ribSupport.routeAttributesIdentifier());
+ }
+
+ @Test
+ public void testRoutesCaseClass() {
+ Assert.assertEquals(L3vpnMcastRoutesIpv4Case.class, this.ribSupport.routesCaseClass());
+ }
+
+ @Test
+ public void testRoutesContainerClass() {
+ Assert.assertEquals(L3vpnMcastRoutesIpv4.class, this.ribSupport.routesContainerClass());
+ }
+
+ @Test
+ public void testRoutesListClass() {
+ Assert.assertEquals(L3vpnMcastRoute.class, this.ribSupport.routesListClass());
+ }
+
+ @Test
+ public void testChangedRoutes() {
+ final Routes emptyCase = new L3vpnMcastRoutesIpv4CaseBuilder().build();
+ DataTreeCandidateNode tree = DataTreeCandidates.fromNormalizedNode(getRoutePath(),
+ createRoutes(emptyCase)).getRootNode();
+ assertTrue(this.ribSupport.changedRoutes(tree).isEmpty());
+
+ final Routes emptyRoutes
+ = new L3vpnMcastRoutesIpv4CaseBuilder()
+ .setL3vpnMcastRoutesIpv4(new L3vpnMcastRoutesIpv4Builder().build()).build();
+ tree = DataTreeCandidates.fromNormalizedNode(getRoutePath(), createRoutes(emptyRoutes)).getRootNode();
+ assertTrue(this.ribSupport.changedRoutes(tree).isEmpty());
+
+ final Routes routes = new L3vpnMcastRoutesIpv4CaseBuilder().setL3vpnMcastRoutesIpv4(MCAST_L3VPN_ROUTES).build();
+ tree = DataTreeCandidates.fromNormalizedNode(getRoutePath(), createRoutes(routes)).getRootNode();
+ final Collection<DataTreeCandidateNode> result = this.ribSupport.changedRoutes(tree);
+ assertFalse(result.isEmpty());
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn.mcast;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Collection;
+import java.util.Collections;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupportTest;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.bgp.rib.rib.loc.rib.tables.routes.L3vpnMcastRoutesIpv6Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.bgp.rib.rib.loc.rib.tables.routes.L3vpnMcastRoutesIpv6CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.L3vpnMcastRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.L3vpnMcastRouteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.L3vpnMcastRouteKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv6.L3vpnMcastRoutesIpv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.routes.ipv6.L3vpnMcastRoutesIpv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv6AdvertizedCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationL3vpnMcastIpv6AdvertizedCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.l3vpn.mcast.ipv6.advertized._case.DestinationIpv6L3vpnMcastBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv6WithdrawnCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationL3vpnMcastIpv6WithdrawnCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.PathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.Update;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
+
+public class L3vpnMcastIpv6RIBSupportTest extends AbstractRIBSupportTest<L3vpnMcastRoutesIpv6Case, L3vpnMcastRoutesIpv6,
+ L3vpnMcastRoute, L3vpnMcastRouteKey> {
+ private static final PathId PATH_ID = new PathId(0L);
+ private static final IpPrefix IPV6_PREFIX = new IpPrefix(new Ipv6Prefix("2001:db8:1:1::/64"));
+ private static final RouteDistinguisher RD = new RouteDistinguisher(new RdIpv4("1.2.3.4:258"));
+ private static final L3vpnMcastRouteKey ROUTE_KEY
+ = new L3vpnMcastRouteKey(PATH_ID, "gAABAQIDBAECIAENuAABAAEAAAAAAAAAAEAAAAAAAAAA");
+ private static final L3vpnMcastRoute ROUTE = new L3vpnMcastRouteBuilder()
+ .setRouteKey(ROUTE_KEY.getRouteKey())
+ .setPathId(ROUTE_KEY.getPathId())
+ .setAttributes(ATTRIBUTES)
+ .setRouteDistinguisher(RD)
+ .setPrefix(IPV6_PREFIX)
+ .build();
+ private static final L3vpnMcastRoutesIpv6 MCAST_L3VPN_ROUTES
+ = new L3vpnMcastRoutesIpv6Builder().setL3vpnMcastRoute(Collections.singletonList(ROUTE)).build();
+
+ private static final L3vpnMcastDestination MCAST_L3VPN_DESTINATION = new L3vpnMcastDestinationBuilder()
+ .setRouteDistinguisher(RD)
+ .setPrefix(IPV6_PREFIX)
+ .setPathId(PATH_ID)
+ .build();
+ private static final DestinationL3vpnMcastIpv6AdvertizedCase REACH_NLRI
+ = new DestinationL3vpnMcastIpv6AdvertizedCaseBuilder()
+ .setDestinationIpv6L3vpnMcast(new DestinationIpv6L3vpnMcastBuilder()
+ .setL3vpnMcastDestination(Collections.singletonList(MCAST_L3VPN_DESTINATION)).build()).build();
+ private static final DestinationL3vpnMcastIpv6WithdrawnCase UNREACH_NLRI
+ = new DestinationL3vpnMcastIpv6WithdrawnCaseBuilder()
+ .setDestinationIpv6L3vpnMcast(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp
+ .l3vpn.mcast.rev180417.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
+ .destination.l3vpn.mcast.ipv6.withdrawn._case.DestinationIpv6L3vpnMcastBuilder()
+ .setL3vpnMcastDestination(Collections.singletonList(MCAST_L3VPN_DESTINATION)).build()).build();
+
+ private L3VpnMcastIpv6RIBSupport ribSupport;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ ribSupport = L3VpnMcastIpv6RIBSupport.getInstance(this.mappingService);
+ setUpTestCustomizer(ribSupport);
+ }
+
+ @Test
+ public void testDeleteRoutes() {
+ final ContainerNode withdraw = createNlriWithDrawnRoute(UNREACH_NLRI);
+ this.ribSupport.deleteRoutes(this.tx, getTablePath(), withdraw);
+ final InstanceIdentifier<L3vpnMcastRoute> instanceIdentifier = this.deletedRoutes.get(0);
+ assertEquals(ROUTE_KEY, instanceIdentifier.firstKeyOf(L3vpnMcastRoute.class));
+ }
+
+ @Test
+ public void testPutRoutes() {
+ this.ribSupport.putRoutes(this.tx, getTablePath(), createNlriAdvertiseRoute(REACH_NLRI), createAttributes());
+ final L3vpnMcastRoute route = (L3vpnMcastRoute) this.insertedRoutes.get(0).getValue();
+ assertEquals(ROUTE, route);
+ }
+
+
+ @Test
+ public void testEmptyRoute() {
+ final Routes empty = new L3vpnMcastRoutesIpv6CaseBuilder()
+ .setL3vpnMcastRoutesIpv6(new L3vpnMcastRoutesIpv6Builder()
+ .setL3vpnMcastRoute(Collections.emptyList()).build()).build();
+ final ChoiceNode expected = createRoutes(empty);
+ Assert.assertEquals(expected, this.ribSupport.emptyRoutes());
+ }
+
+ @Test
+ public void testBuildMpUnreachNlriUpdate() {
+ final Collection<MapEntryNode> routes = createRoutes(MCAST_L3VPN_ROUTES);
+ final Update update = this.ribSupport.buildUpdate(Collections.emptyList(), routes, ATTRIBUTES);
+ assertEquals(UNREACH_NLRI, update.getAttributes().augmentation(Attributes2.class).getMpUnreachNlri()
+ .getWithdrawnRoutes().getDestinationType());
+ assertNull(update.getAttributes().augmentation(Attributes1.class));
+ }
+
+ @Test
+ public void testBuildMpReachNlriUpdate() {
+ final Collection<MapEntryNode> routes = createRoutes(MCAST_L3VPN_ROUTES);
+ final Update update = this.ribSupport.buildUpdate(routes, Collections.emptyList(), ATTRIBUTES);
+ assertEquals(REACH_NLRI, update.getAttributes().augmentation(Attributes1.class).getMpReachNlri()
+ .getAdvertizedRoutes().getDestinationType());
+ assertNull(update.getAttributes().augmentation(Attributes2.class));
+ }
+
+ @Test
+ public void testCacheableNlriObjects() {
+ Assert.assertEquals(ImmutableSet.of(L3vpnMcastRoutesIpv6Case.class), this.ribSupport.cacheableNlriObjects());
+ }
+
+ @Test
+ public void testCacheableAttributeObjects() {
+ Assert.assertEquals(ImmutableSet.of(), this.ribSupport.cacheableAttributeObjects());
+ }
+
+ @Test
+ public void testRouteIdAddPath() {
+ Assert.assertEquals(ROUTE_KEY, this.ribSupport.createRouteListKey(ROUTE_KEY.getPathId().getValue(),
+ ROUTE_KEY.getRouteKey()));
+ }
+
+ @Test
+ public void testRoutePath() {
+ final YangInstanceIdentifier.NodeIdentifierWithPredicates prefixNii = createRouteNIWP(MCAST_L3VPN_ROUTES);
+ final YangInstanceIdentifier expected = getRoutePath().node(prefixNii);
+ final YangInstanceIdentifier actual = this.ribSupport.routePath(getTablePath().node(Routes.QNAME), prefixNii);
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testRouteAttributesIdentifier() {
+ Assert.assertEquals(new YangInstanceIdentifier.NodeIdentifier(
+ Attributes.QNAME.withModule(BindingReflections.getQNameModule(L3vpnMcastRoutesIpv6Case.class))),
+ this.ribSupport.routeAttributesIdentifier());
+ }
+
+ @Test
+ public void testRoutesCaseClass() {
+ Assert.assertEquals(L3vpnMcastRoutesIpv6Case.class, this.ribSupport.routesCaseClass());
+ }
+
+ @Test
+ public void testRoutesContainerClass() {
+ Assert.assertEquals(L3vpnMcastRoutesIpv6.class, this.ribSupport.routesContainerClass());
+ }
+
+ @Test
+ public void testRoutesListClass() {
+ Assert.assertEquals(L3vpnMcastRoute.class, this.ribSupport.routesListClass());
+ }
+
+ @Test
+ public void testChangedRoutes() {
+ final Routes emptyCase = new L3vpnMcastRoutesIpv6CaseBuilder().build();
+ DataTreeCandidateNode tree = DataTreeCandidates.fromNormalizedNode(getRoutePath(),
+ createRoutes(emptyCase)).getRootNode();
+ assertTrue(this.ribSupport.changedRoutes(tree).isEmpty());
+
+ final Routes emptyRoutes
+ = new L3vpnMcastRoutesIpv6CaseBuilder()
+ .setL3vpnMcastRoutesIpv6(new L3vpnMcastRoutesIpv6Builder().build()).build();
+ tree = DataTreeCandidates.fromNormalizedNode(getRoutePath(), createRoutes(emptyRoutes)).getRootNode();
+ assertTrue(this.ribSupport.changedRoutes(tree).isEmpty());
+
+ final Routes routes = new L3vpnMcastRoutesIpv6CaseBuilder().setL3vpnMcastRoutesIpv6(MCAST_L3VPN_ROUTES).build();
+ tree = DataTreeCandidates.fromNormalizedNode(getRoutePath(), createRoutes(routes)).getRootNode();
+ final Collection<DataTreeCandidateNode> result = this.ribSupport.changedRoutes(tree);
+ assertFalse(result.isEmpty());
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.l3vpn.mcast.nlri;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.Collections;
+import org.junit.Test;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.l3vpn.mcast.rev180417.l3vpn.mcast.destination.L3vpnMcastDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+
+public class L3vpnMcastNlriSerializerTest {
+ private static final byte[] EXPECTED = new byte[]{
+ (byte) 0x80,
+ 0, 1, 1, 2, 3, 4, 1, 2, //RD
+ 32, 1, 13, (byte) 0xb8, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 64, // Prefix
+ 0, 0, 0, 0, 0, 0, 0 //trailing bits
+ };
+ private static final RouteDistinguisher RD = new RouteDistinguisher(new RdIpv4("1.2.3.4:258"));
+ private static final IpPrefix IPV6_PREFIX = new IpPrefix(new Ipv6Prefix("2001:db8:1:2::/64"));
+ private static final L3vpnMcastDestination MCAST_L3VPN_DESTINATION = new L3vpnMcastDestinationBuilder()
+ .setRouteDistinguisher(RD)
+ .setPrefix(IPV6_PREFIX)
+ .build();
+
+ @Test
+ public void testL3vpnMcastNlriSerializer() {
+ ByteBuf actual = Unpooled.buffer();
+ L3vpnMcastNlriSerializer.serializeNlri(Collections.singletonList(MCAST_L3VPN_DESTINATION), actual);
+ assertArrayEquals(EXPECTED, ByteArray.getAllBytes(actual));
+ }
+}
\ No newline at end of file