Provide a way to convert MpReach to MpUnreach 99/78799/4
authorMatej Perina <matej.perina@pantheon.tech>
Fri, 14 Dec 2018 14:04:10 +0000 (15:04 +0100)
committerRobert Varga <nite@hq.sk>
Fri, 14 Dec 2018 17:06:33 +0000 (17:06 +0000)
BGPUpdateParser needs the ability to convert MP_REACH attributes
to MP_UNREACH equivalents, potentially merging an existing
MP_UNREACH attribute into the mix.

This patch adds that capability by adding teach NlriRegistry to
perform the conversion.

JIRA: BGPCEP-359
Change-Id: I3f3330145b1e4851335f44a0f9183cd1b6c83ea5
Signed-off-by: Matej Perina <matej.perina@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
bgp/extensions/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/EvpnNlriParser.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/NlriParser.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/NlriRegistry.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleNlriRegistry.java

index 42e9be00d42c7389defef9653212b8584cb84bdf..0eea81e913e5350b8bd25029b98624ba8994ccc2 100644 (file)
@@ -35,6 +35,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn
 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.MpReachNlri;
 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.MpUnreachNlri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
@@ -174,4 +175,35 @@ public final class EvpnNlriParser implements NlriParser, NlriSerializer {
         }
         output.writeBytes(nlriOutput);
     }
+
+    @Override
+    public boolean convertMpReachToMpUnReach(final MpReachNlri mpReachNlri, final MpUnreachNlriBuilder builder) {
+        final WithdrawnRoutesBuilder withdrawnRoutes = new WithdrawnRoutesBuilder(builder.getWithdrawnRoutes());
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.update.attributes.mp
+                .unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCaseBuilder destinationType =
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.update
+                        .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCaseBuilder(
+                                (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329
+                                        .update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
+                                        .DestinationEvpnCase) withdrawnRoutes.getDestinationType());
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev180329.update.attributes.mp
+                .unreach.nlri.withdrawn.routes.destination.type.destination.evpn._case.DestinationEvpnBuilder
+                destinationEvpn = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn
+                .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.evpn._case
+                .DestinationEvpnBuilder(destinationType.getDestinationEvpn());
+        List<EvpnDestination> evpnDestination = destinationEvpn.getEvpnDestination();
+        if (evpnDestination == null) {
+            evpnDestination = new ArrayList<>();
+        }
+        evpnDestination.addAll(((DestinationEvpnCase) mpReachNlri.getAdvertizedRoutes().getDestinationType())
+                .getDestinationEvpn().getEvpnDestination());
+        builder.setWithdrawnRoutes(withdrawnRoutes
+                .setDestinationType(destinationType
+                        .setDestinationEvpn(destinationEvpn
+                                .setEvpnDestination(evpnDestination)
+                                .build())
+                        .build())
+                .build());
+        return true;
+    }
 }
index 2bff6a2cf52dd46b3f50c951be75f286dc0b161e..5f542e5cfae3f6cf152d4f555977a5c157143d19 100644 (file)
@@ -11,6 +11,7 @@ import io.netty.buffer.ByteBuf;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlri;
 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;
 
@@ -39,4 +40,16 @@ public interface NlriParser {
      */
     void parseNlri(@Nonnull ByteBuf nlri, @Nonnull MpUnreachNlriBuilder builder,
             @Nullable PeerSpecificParserConstraint constraint) throws BGPParsingException;
+
+    /**
+     * Convert MP_REACH attribute and merge it to existing MpUnreachNlriBuilder.
+     *
+     * @param mpReachNlri MP_REACH attribute to be converted
+     * @param builder to which converted routing information should be added
+     * @return True if the conversion was successful, false otherwise
+     */
+    default boolean convertMpReachToMpUnReach(@Nonnull final MpReachNlri mpReachNlri,
+            @Nonnull final MpUnreachNlriBuilder builder) {
+        return false;
+    }
 }
index db711df6d9a972b682d6e18be1f1f944fdc13344..b3ff367f89ef96228a73eee7bd44ca53876d9f08 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.protocol.bgp.parser.spi;
 
 import io.netty.buffer.ByteBuf;
+import java.util.Optional;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
@@ -60,4 +61,17 @@ public interface NlriRegistry {
      * @return Iterable of NLRI serializers.
      */
     Iterable<NlriSerializer> getSerializers();
+
+    /**
+     * Convert MP_REACH attribute to MP_UNREACH attribute and merge it with original one if it exists.
+     *
+     * <p>
+     * The default implementation rejects the conversion.
+     *
+     * @param mpReachNlri MP_REACH attribute to be converted
+     * @param mpUnreachNlri original MP_UNREACH attribute
+     * @return resulting MP_UNREACH attribute after conversion
+     */
+    Optional<MpUnreachNlri> convertMpReachToMpUnReach(@Nonnull MpReachNlri mpReachNlri,
+            @Nullable MpUnreachNlri mpUnreachNlri);
 }
index 1270c36a1f54d16d9d1c1464276c516db80e2496..7b3658504000cacb072be174e3d1aa491357f868 100644 (file)
@@ -15,6 +15,7 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.AbstractMap.SimpleEntry;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import org.opendaylight.bgp.concepts.NextHopUtil;
@@ -33,6 +34,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 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.MpUnreachNlri;
 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.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.SubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.CNextHop;
@@ -231,4 +233,26 @@ final class SimpleNlriRegistry implements NlriRegistry {
         }
         return builder.build();
     }
+
+    @Override
+    public Optional<MpUnreachNlri> convertMpReachToMpUnReach(final MpReachNlri mpReachNlri,
+            final MpUnreachNlri mpUnreachNlri) {
+        if (mpUnreachNlri == null) {
+            return Optional.of(new MpUnreachNlriBuilder()
+                    .setWithdrawnRoutes(new WithdrawnRoutesBuilder()
+                            .setDestinationType(mpReachNlri.getAdvertizedRoutes().getDestinationType())
+                            .build())
+                    .build());
+        }
+
+        final BgpTableType key = createKey(mpUnreachNlri.getAfi(), mpUnreachNlri.getSafi());
+        final NlriParser parser = this.handlers.get(key);
+        if (parser == null) {
+            LOG.debug("Parser for {} not found", key);
+            return Optional.empty();
+        }
+
+        final MpUnreachNlriBuilder builder = new MpUnreachNlriBuilder(mpUnreachNlri);
+        return parser.convertMpReachToMpUnReach(mpReachNlri, builder) ? Optional.of(builder.build()) : Optional.empty();
+    }
 }