Sanitize flowspec parsing 29/105629/2
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 23 Apr 2023 17:26:19 +0000 (19:26 +0200)
committerRobert Varga <nite@hq.sk>
Sun, 23 Apr 2023 20:55:12 +0000 (20:55 +0000)
Flowspec support performs a rather ugly indirection through Object[] to
deal with the fact that base and L3VPN routes have different structure.

The problem core issue here is lack of proper specialization, where
AbstractFlowspec{NlriParser,RIBSupport} really cater to plain Ipv4/Ipv6
supports -- and thus there is no simple-specific meeting point.

Introduce AbstractFlowspecIp{NlriParser,RIBSupport} to act as proper
specialization, which allows us to structure the code correctly.

This patch deals with the parsing path, leaving the serialization path
to a follow-up.

Change-Id: Ifdc3241c9f87c06eec112550103e67b26973c80f
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
12 files changed:
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecIpNlriParser.java [new file with mode: 0644]
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecIpRIBSupport.java [new file with mode: 0644]
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecNlriParser.java
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecRIBSupport.java
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FlowspecIpv4RIBSupport.java
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FlowspecIpv6RIBSupport.java
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParser.java
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParser.java
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/AbstractFlowspecL3vpnNlriParser.java
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/AbstractFlowspecL3vpnRIBSupport.java
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv4/FlowspecL3vpnIpv4NlriParser.java
bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv6/FlowspecL3vpnIpv6NlriParser.java

diff --git a/bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecIpNlriParser.java b/bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecIpNlriParser.java
new file mode 100644 (file)
index 0000000..918def3
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. 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.flowspec;
+
+import io.netty.buffer.ByteBuf;
+import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.Flowspec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
+
+abstract class AbstractFlowspecIpNlriParser extends AbstractFlowspecNlriParser {
+    AbstractFlowspecIpNlriParser(final FlowspecTypeRegistry flowspecTypeRegistry) {
+        super(flowspecTypeRegistry);
+    }
+
+    @Override
+    protected final DestinationType parseAdvertizedNlri(final ByteBuf nlri, final PathId pathId)
+            throws BGPParsingException {
+        return createAdvertizedRoutesDestinationType(parseNlriFlowspecList(nlri), pathId);
+    }
+
+    abstract @NonNull DestinationType createAdvertizedRoutesDestinationType(List<Flowspec> flowspecList,
+        @Nullable PathId pathId);
+
+    @Override
+    protected final DestinationType parseWithdrawnNlri(final ByteBuf nlri, final PathId pathId)
+            throws BGPParsingException {
+        return createWithdrawnDestinationType(parseNlriFlowspecList(nlri), pathId);
+    }
+
+    abstract @NonNull DestinationType createWithdrawnDestinationType(List<Flowspec> flowspecList,
+        @Nullable PathId pathId);
+}
diff --git a/bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecIpRIBSupport.java b/bgp/extensions/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecIpRIBSupport.java
new file mode 100644 (file)
index 0000000..08da53a
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. 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.flowspec;
+
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.Route;
+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.rev200120.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.SubsequentAddressFamily;
+import org.opendaylight.yangtools.yang.binding.ChildOf;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+
+abstract class AbstractFlowspecIpRIBSupport<
+        T extends AbstractFlowspecIpNlriParser,
+        C extends Routes & DataObject,
+        S extends ChildOf<? super C>,
+        R extends Route & ChildOf<? super S> & Identifiable<?>> extends AbstractFlowspecRIBSupport<T, C, S, R> {
+    AbstractFlowspecIpRIBSupport(final BindingNormalizedNodeSerializer mappingService, final Class<C> cazeClass,
+            final Class<S> containerClass, final Class<R> listClass, final AddressFamily afiClass,
+            final SubsequentAddressFamily safiClass, final QName dstContainerClassQName, final T nlriParser) {
+        super(mappingService, cazeClass, containerClass, listClass, afiClass, safiClass, dstContainerClassQName,
+            nlriParser);
+    }
+
+    @Override
+    protected final DestinationType buildDestination(final MapEntryNode route, final PathId pathId) {
+        return nlriParser.createAdvertizedRoutesDestinationType(nlriParser.extractFlowspec(route), pathId);
+    }
+
+    @Override
+    protected final DestinationType buildWithdrawnDestination(final MapEntryNode route, final PathId pathId) {
+        return nlriParser.createWithdrawnDestinationType(nlriParser.extractFlowspec(route), pathId);
+    }
+}
index 00f4932950735299b67d0e4334e8a3b0c11426c6..1e09cdbc246a86fd6b6e06936d2199a23a9e09fe 100644 (file)
@@ -164,26 +164,6 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
 
     protected abstract void stringSpecificFSNlriType(FlowspecType value, StringBuilder buffer);
 
-    /**
-     * Create withdrawn destination type.
-     *
-     * @param nlriFields a list of NLRI fields to be included in the destination type
-     * @param pathId     associated path id with given NLRI
-     * @return created destination type
-     */
-    public abstract DestinationType createWithdrawnDestinationType(Object @NonNull[] nlriFields,
-            @Nullable PathId pathId);
-
-    /**
-     * Create advertized destination type.
-     *
-     * @param nlriFields a list of NLRI fields to be included in the destination type
-     * @param pathId     associated path id with given NLRI
-     * @return created destination type
-     */
-    public abstract DestinationType createAdvertizedRoutesDestinationType(Object @NonNull[] nlriFields,
-            @Nullable PathId pathId);
-
     @Override
     public final void serializeAttribute(final Attributes pathAttributes, final ByteBuf byteAggregator) {
         final AttributesReach pathAttributes1 = pathAttributes.augmentation(AttributesReach.class);
@@ -590,6 +570,7 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
      * @param nlri byte representation of NLRI which will be parsed
      * @return list of Flowspec
      */
+    // FIXME: throws BGPParsingException
     protected final List<Flowspec> parseNlriFlowspecList(final @NonNull ByteBuf nlri) {
         if (!nlri.isReadable()) {
             return null;
@@ -617,44 +598,52 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
         return fss;
     }
 
-    /**
-     * Override this function to parse additional NLRI fields.
-     *
-     * @param nlri NLRI buffer
-     * @return Parsed additional fields
-     */
-    protected Object @NonNull[] parseNlri(final @NonNull ByteBuf nlri) throws BGPParsingException {
-        return new Object[] {parseNlriFlowspecList(nlri)};
-    }
-
     @Override
-    public final void parseNlri(final @NonNull ByteBuf nlri, final @NonNull MpReachNlriBuilder builder,
+    public final void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder,
             final PeerSpecificParserConstraint constraint) throws BGPParsingException {
         if (!nlri.isReadable()) {
             return;
         }
         final PathId pathId = readPathId(nlri, builder.getAfi(), builder.getSafi(), constraint);
-        final Object[] nlriFields = parseNlri(nlri);
         builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder()
-            .setDestinationType(createAdvertizedRoutesDestinationType(nlriFields, pathId))
+            .setDestinationType(parseAdvertizedNlri(nlri, pathId))
             .build());
     }
 
     @Override
-    public final void parseNlri(final @NonNull ByteBuf nlri, final @NonNull MpUnreachNlriBuilder builder,
+    public final void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder,
             final PeerSpecificParserConstraint constraint) throws BGPParsingException {
         if (!nlri.isReadable()) {
             return;
         }
         final PathId pathId = readPathId(nlri, builder.getAfi(), builder.getSafi(), constraint);
-        final Object[] nlriFields = parseNlri(nlri);
         builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder()
-            .setDestinationType(createWithdrawnDestinationType(nlriFields, pathId))
+            .setDestinationType(parseWithdrawnNlri(nlri, pathId))
             .build()
         );
     }
 
-    protected static @Nullable PathId readPathId(final @NonNull ByteBuf nlri, final AddressFamily afi,
+    /**
+     * Create advertized destination type.
+     *
+     * @param nlri   on-wire NLRI, with path ID already peeled
+     * @param pathId associated path id with given NLRI
+     * @return created destination type
+     */
+    protected abstract @NonNull DestinationType parseAdvertizedNlri(@NonNull ByteBuf nlri, @Nullable PathId pathId)
+        throws BGPParsingException;
+
+    /**
+     * Parse and create withdrawn destination type.
+     *
+     * @param nlri   on-wire NLRI, with path ID already peeled
+     * @param pathId associated path id with given NLRI
+     * @return created destination type
+     */
+    protected abstract @NonNull DestinationType parseWithdrawnNlri(@NonNull ByteBuf nlri, @Nullable PathId pathId)
+        throws BGPParsingException;
+
+    protected static final @Nullable PathId readPathId(final @NonNull ByteBuf nlri, final AddressFamily afi,
             final SubsequentAddressFamily safi, final PeerSpecificParserConstraint constraint) {
         if (MultiPathSupportUtil.isTableTypeSupported(constraint, new BgpTableTypeImpl(afi, safi))) {
             return PathIdUtil.readPathId(nlri);
index 86dd1cf95ff5afbe67896873ccd32825172d9fd1..44241171199f500f247a29ab955fed01b0ca4fe8 100644 (file)
@@ -13,6 +13,8 @@ import com.google.common.annotations.Beta;
 import com.google.common.collect.Iterables;
 import java.util.Collection;
 import java.util.Collections;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
 import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
@@ -38,7 +40,7 @@ public abstract class AbstractFlowspecRIBSupport<
         C extends Routes & DataObject,
         S extends ChildOf<? super C>,
         R extends Route & ChildOf<? super S> & Identifiable<?>> extends AbstractRIBSupport<C, S, R> {
-    protected final T nlriParser;
+    protected final @NonNull T nlriParser;
 
     protected AbstractFlowspecRIBSupport(
             final BindingNormalizedNodeSerializer mappingService,
@@ -55,25 +57,21 @@ public abstract class AbstractFlowspecRIBSupport<
     }
 
     @Override
-    protected DestinationType buildDestination(final Collection<MapEntryNode> routes) {
-        final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
-        final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
-        return nlriParser.createAdvertizedRoutesDestinationType(
-            new Object[] {nlriParser.extractFlowspec(routesCont)},
-            pathId
-        );
+    protected final DestinationType buildDestination(final Collection<MapEntryNode> routes) {
+        final var route = Iterables.getOnlyElement(routes);
+        return buildDestination(route, PathIdUtil.buildPathId(route, routePathIdNid()));
     }
 
+    protected abstract @NonNull DestinationType buildDestination(MapEntryNode route, @Nullable PathId pathId);
+
     @Override
-    protected DestinationType buildWithdrawnDestination(final Collection<MapEntryNode> routes) {
-        final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
-        final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
-        return nlriParser.createWithdrawnDestinationType(
-            new Object[] {nlriParser.extractFlowspec(Iterables.getOnlyElement(routes))},
-            pathId
-        );
+    protected final DestinationType buildWithdrawnDestination(final Collection<MapEntryNode> routes) {
+        final var route = Iterables.getOnlyElement(routes);
+        return buildWithdrawnDestination(route, PathIdUtil.buildPathId(route, routePathIdNid()));
     }
 
+    protected abstract @NonNull DestinationType buildWithdrawnDestination(MapEntryNode route, @Nullable PathId pathId);
+
     @Override
     protected final Collection<NodeIdentifierWithPredicates> processDestination(
         final DOMDataTreeWriteTransaction tx,
index 589708b8dff9148c40cc5d21fec126b7e68bf76a..cb30b228ae78c91c5611baeb43631a09db3be757 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flow
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
 
 public final class FlowspecIpv4RIBSupport
-        extends AbstractFlowspecRIBSupport<SimpleFlowspecIpv4NlriParser,
+        extends AbstractFlowspecIpRIBSupport<SimpleFlowspecIpv4NlriParser,
         FlowspecRoutesCase,
         FlowspecRoutes,
         FlowspecRoute> {
index e32d1f968cea68d50ef9b72920a0725385adf054..06adc6a9bd3e4681588e99cf9c74e872465658bf 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flow
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv6AddressFamily;
 
 public final class FlowspecIpv6RIBSupport
-        extends AbstractFlowspecRIBSupport<SimpleFlowspecIpv6NlriParser,
+        extends AbstractFlowspecIpRIBSupport<SimpleFlowspecIpv6NlriParser,
         FlowspecIpv6RoutesCase,
         FlowspecIpv6Routes,
         FlowspecRoute> {
index 6eeaa891d73091f5cddf16def08a2c568ccb506d..64a56ef235c91e0acd150f7257a18ff24ace8cd9 100644 (file)
@@ -21,33 +21,31 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 
-public final class SimpleFlowspecIpv4NlriParser extends AbstractFlowspecNlriParser {
+public final class SimpleFlowspecIpv4NlriParser extends AbstractFlowspecIpNlriParser {
     public SimpleFlowspecIpv4NlriParser(final SAFI safi) {
         super(FlowspecTypeRegistries.getFlowspecTypeRegistry(AFI.IPV4, safi));
     }
 
     @Override
-    public DestinationType createWithdrawnDestinationType(final Object[] nlriFields, final PathId pathId) {
-        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
+    DestinationType createAdvertizedRoutesDestinationType(final List<Flowspec> flowspecList, final PathId pathId) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
-                .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
-            .setDestinationFlowspecIpv4(
-                new DestinationFlowspecIpv4Builder()
-                    .setFlowspec(flowspecList)
-                    .setPathId(pathId)
-                    .build()
-            ).build();
+            .attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
+            .setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder()
+                .setFlowspec(flowspecList)
+                .setPathId(pathId)
+                .build())
+            .build();
     }
 
     @Override
-    public DestinationType createAdvertizedRoutesDestinationType(final Object[] nlriFields, final PathId pathId) {
-        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
+    DestinationType createWithdrawnDestinationType(final List<Flowspec> flowspecList, final PathId pathId) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
-                .attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
-                .setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder()
-                    .setFlowspec(flowspecList)
-                    .setPathId(pathId)
-                    .build()).build();
+            .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
+            .setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder()
+                .setFlowspec(flowspecList)
+                .setPathId(pathId)
+                .build())
+            .build();
     }
 
     @Override
index 0787efab6ad86ae4843742bf75fb08b154923cac..9317adb1226bbc47a6c2532f2a1a5b87b6a95571 100644 (file)
@@ -21,35 +21,31 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 
-public final class SimpleFlowspecIpv6NlriParser extends AbstractFlowspecNlriParser {
+public final class SimpleFlowspecIpv6NlriParser extends AbstractFlowspecIpNlriParser {
     public SimpleFlowspecIpv6NlriParser(final SAFI safi) {
         super(FlowspecTypeRegistries.getFlowspecTypeRegistry(AFI.IPV6, safi));
     }
 
     @Override
-    public DestinationType createWithdrawnDestinationType(final Object[] nlriFields, final PathId pathId) {
-        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
+    DestinationType createAdvertizedRoutesDestinationType(final List<Flowspec> flowspecList, final PathId pathId) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
-                .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-            .setDestinationFlowspecIpv6(
-                new DestinationFlowspecIpv6Builder()
-                    .setFlowspec(flowspecList)
-                    .setPathId(pathId)
-                    .build()
-            ).build();
+            .attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
+            .setDestinationFlowspecIpv6(new DestinationFlowspecIpv6Builder()
+                .setFlowspec(flowspecList)
+                .setPathId(pathId)
+                .build())
+            .build();
     }
 
     @Override
-    public DestinationType createAdvertizedRoutesDestinationType(final Object[] nlriFields, final PathId pathId) {
-        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
+    DestinationType createWithdrawnDestinationType(final List<Flowspec> flowspecList, final PathId pathId) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
-                .attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-            .setDestinationFlowspecIpv6(
-                new DestinationFlowspecIpv6Builder()
-                    .setFlowspec(flowspecList)
-                    .setPathId(pathId)
-                    .build()
-            ).build();
+            .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
+            .setDestinationFlowspecIpv6(new DestinationFlowspecIpv6Builder()
+                .setFlowspec(flowspecList)
+                .setPathId(pathId)
+                .build())
+            .build();
     }
 
     @Override
index c033d793a066ad4681a93bdfbaa2ea82489d5f14..7759d3469a68ac0e3ae8ecadf95556651d86148b 100644 (file)
@@ -13,11 +13,16 @@ import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.extractRouteD
 import io.netty.buffer.ByteBuf;
 import java.util.ArrayList;
 import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
 import org.opendaylight.protocol.bgp.flowspec.AbstractFlowspecNlriParser;
 import org.opendaylight.protocol.bgp.flowspec.FlowspecTypeRegistry;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.Flowspec;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.FlowspecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
@@ -35,7 +40,7 @@ public abstract class AbstractFlowspecL3vpnNlriParser extends AbstractFlowspecNl
     }
 
     @Override
-    public String stringNlri(final DataContainerNode flowspec) {
+    public final String stringNlri(final DataContainerNode flowspec) {
         final StringBuilder buffer = new StringBuilder();
         final RouteDistinguisher rd = extractRouteDistinguisher(flowspec, RD_NID);
         if (rd != null) {
@@ -55,7 +60,7 @@ public abstract class AbstractFlowspecL3vpnNlriParser extends AbstractFlowspecNl
     }
 
     @Override
-    protected void serializeNlri(final Object[] nlriFields, final ByteBuf buffer) {
+    protected final void serializeNlri(final Object[] nlriFields, final ByteBuf buffer) {
         final RouteDistinguisher rd = requireNonNull((RouteDistinguisher) nlriFields[0]);
         RouteDistinguisherUtil.serializeRouteDistinquisher(rd, buffer);
         final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
@@ -63,26 +68,52 @@ public abstract class AbstractFlowspecL3vpnNlriParser extends AbstractFlowspecNl
     }
 
     @Override
-    protected Object[] parseNlri(final ByteBuf nlri) {
+    protected final DestinationType parseAdvertizedNlri(final ByteBuf nlri, final PathId pathId)
+            throws BGPParsingException {
         readNlriLength(nlri);
-        return new Object[] {
-            requireNonNull(readRouteDistinguisher(nlri)),
-            parseL3vpnNlriFlowspecList(nlri)
-        };
+        return createAdvertizedRoutesDestinationType(requireNonNull(readRouteDistinguisher(nlri)),
+            parseL3vpnNlriFlowspecList(nlri), pathId);
     }
 
-    protected final List<Flowspec> parseL3vpnNlriFlowspecList(final ByteBuf nlri) {
+    /**
+     * Create advertized destination type.
+     *
+     * @param rd           the RouteDistinguisher
+     * @param flowspecList a list of {@link Flowspec}s
+     * @param pathId       associated path id with given destination
+     * @return created destination type
+     */
+    protected abstract @NonNull DestinationType createAdvertizedRoutesDestinationType(RouteDistinguisher rd,
+        @Nullable List<Flowspec> flowspecList, @Nullable PathId pathId);
+
+    @Override
+    protected final DestinationType parseWithdrawnNlri(final ByteBuf nlri, final PathId pathId)
+            throws BGPParsingException {
+        readNlriLength(nlri);
+        return createWithdrawnDestinationType(requireNonNull(readRouteDistinguisher(nlri)),
+            parseL3vpnNlriFlowspecList(nlri), pathId);
+    }
+
+    /**
+     * Create withdrawn destination type.
+     *
+     * @param rd           the RouteDistinguisher
+     * @param flowspecList a list of {@link Flowspec}s
+     * @param pathId       associated path id with given destination
+     * @return created destination type
+     */
+    protected abstract @NonNull DestinationType createWithdrawnDestinationType(RouteDistinguisher rd,
+        @Nullable List<Flowspec> flowspecList, @Nullable PathId pathId);
+
+    private @Nullable List<Flowspec> parseL3vpnNlriFlowspecList(final ByteBuf nlri) {
         if (!nlri.isReadable()) {
             return null;
         }
-        final List<Flowspec> fss = new ArrayList<>();
 
+        final var fss = new ArrayList<Flowspec>();
         while (nlri.isReadable()) {
-            final FlowspecBuilder builder = new FlowspecBuilder();
-            builder.setFlowspecType(flowspecTypeRegistry.parseFlowspecType(nlri));
-            fss.add(builder.build());
+            fss.add(new FlowspecBuilder().setFlowspecType(flowspecTypeRegistry.parseFlowspecType(nlri)).build());
         }
-
         return fss;
     }
 }
index 6923a8b5d4be4604a844e744256927b7cd52fdb0..abf552d334232d63e7f069b073718e9f8de4b373 100644 (file)
@@ -7,31 +7,25 @@
  */
 package org.opendaylight.protocol.bgp.flowspec.l3vpn;
 
-import com.google.common.collect.Iterables;
-import java.util.Collection;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.protocol.bgp.flowspec.AbstractFlowspecRIBSupport;
-import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.FlowspecL3vpnSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.Route;
 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.rev200120.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
 import org.opendaylight.yangtools.yang.binding.ChildOf;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Identifiable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 
-public abstract class AbstractFlowspecL3vpnRIBSupport
-        <T extends AbstractFlowspecL3vpnNlriParser,
-                C extends Routes & DataObject,
-                S extends ChildOf<? super C>,
-                R extends Route & ChildOf<? super S> & Identifiable<?>>
-        extends AbstractFlowspecRIBSupport<T, C, S, R> {
-
+public abstract class AbstractFlowspecL3vpnRIBSupport<
+        T extends AbstractFlowspecL3vpnNlriParser,
+        C extends Routes & DataObject,
+        S extends ChildOf<? super C>,
+        R extends Route & ChildOf<? super S> & Identifiable<?>> extends AbstractFlowspecRIBSupport<T, C, S, R> {
     protected AbstractFlowspecL3vpnRIBSupport(
             final BindingNormalizedNodeSerializer mappingService,
             final Class<C> cazeClass,
@@ -46,24 +40,14 @@ public abstract class AbstractFlowspecL3vpnRIBSupport
     }
 
     @Override
-    protected DestinationType buildDestination(final Collection<MapEntryNode> routes) {
-        final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
-        final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
-        final RouteDistinguisher rd = extractRouteDistinguisher(routesCont);
-        return this.nlriParser.createAdvertizedRoutesDestinationType(
-                new Object[]{rd, this.nlriParser.extractFlowspec(routesCont)},
-                pathId
-        );
+    protected final DestinationType buildDestination(final MapEntryNode route, final PathId pathId) {
+        return nlriParser.createAdvertizedRoutesDestinationType(extractRouteDistinguisher(route),
+            nlriParser.extractFlowspec(route), pathId);
     }
 
     @Override
-    protected DestinationType buildWithdrawnDestination(final Collection<MapEntryNode> routes) {
-        final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
-        final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
-        final RouteDistinguisher rd = extractRouteDistinguisher(routesCont);
-        return this.nlriParser.createWithdrawnDestinationType(
-                new Object[]{rd, this.nlriParser.extractFlowspec(Iterables.getOnlyElement(routes))},
-                pathId
-        );
+    protected final DestinationType buildWithdrawnDestination(final MapEntryNode route, final PathId pathId) {
+        return nlriParser.createWithdrawnDestinationType(extractRouteDistinguisher(route),
+            nlriParser.extractFlowspec(route), pathId);
     }
 }
index a1970bef7895a4a1aec8c83d5e6290d67ad335c7..981f7e6fc011c436f7642ebe7418112a3799c824 100644 (file)
@@ -35,29 +35,28 @@ public final class FlowspecL3vpnIpv4NlriParser extends AbstractFlowspecL3vpnNlri
     }
 
     @Override
-    public DestinationType createWithdrawnDestinationType(final Object[] nlriFields, final PathId pathId) {
-        final RouteDistinguisher rd = (RouteDistinguisher) nlriFields[0];
-        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
+    protected DestinationType createAdvertizedRoutesDestinationType(final RouteDistinguisher rd,
+            final List<Flowspec> flowspecList, final PathId pathId) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
-                .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
-                .setDestinationFlowspecL3vpnIpv4(new DestinationFlowspecL3vpnIpv4Builder()
-                    .setRouteDistinguisher(rd)
-                    .setFlowspec(flowspecList)
-                    .setPathId(pathId)
-                    .build()).build();
+            .attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
+            .setDestinationFlowspecL3vpnIpv4(new DestinationFlowspecL3vpnIpv4Builder()
+                .setRouteDistinguisher(rd)
+                .setFlowspec(flowspecList)
+                .setPathId(pathId)
+                .build()).build();
     }
 
     @Override
-    public DestinationType createAdvertizedRoutesDestinationType(final Object[] nlriFields, final PathId pathId) {
-        final RouteDistinguisher rd = (RouteDistinguisher) nlriFields[0];
-        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
+    protected DestinationType createWithdrawnDestinationType(final RouteDistinguisher rd,
+            final List<Flowspec> flowspecList, final PathId pathId) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
-                .attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
-                .setDestinationFlowspecL3vpnIpv4(new DestinationFlowspecL3vpnIpv4Builder()
-                    .setRouteDistinguisher(rd)
-                    .setFlowspec(flowspecList)
-                    .setPathId(pathId)
-                    .build()).build();
+            .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
+            .setDestinationFlowspecL3vpnIpv4(new DestinationFlowspecL3vpnIpv4Builder()
+                .setRouteDistinguisher(rd)
+                .setFlowspec(flowspecList)
+                .setPathId(pathId)
+                .build())
+            .build();
     }
 
     @Override
index 08950859ce77a6c1e48c5e9a2fe0da6c48eb9b54..2080001b74b196b3e2c4a4d5b2c90aeb85c0c26a 100644 (file)
@@ -35,29 +35,29 @@ public final class FlowspecL3vpnIpv6NlriParser extends AbstractFlowspecL3vpnNlri
     }
 
     @Override
-    public DestinationType createWithdrawnDestinationType(final Object[] nlriFields, final PathId pathId) {
-        final RouteDistinguisher rd = (RouteDistinguisher) nlriFields[0];
-        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
+    protected DestinationType createAdvertizedRoutesDestinationType(final RouteDistinguisher rd,
+            final List<Flowspec> flowspecList, final PathId pathId) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
-                .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
-                .setDestinationFlowspecL3vpnIpv6(new DestinationFlowspecL3vpnIpv6Builder()
-                    .setRouteDistinguisher(rd)
-                    .setFlowspec(flowspecList)
-                    .setPathId(pathId)
-                    .build()).build();
+            .attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
+            .setDestinationFlowspecL3vpnIpv6(new DestinationFlowspecL3vpnIpv6Builder()
+                .setRouteDistinguisher(rd)
+                .setFlowspec(flowspecList)
+                .setPathId(pathId)
+                .build())
+            .build();
     }
 
     @Override
-    public DestinationType createAdvertizedRoutesDestinationType(final Object[] nlriFields, final PathId pathId) {
-        final RouteDistinguisher rd = (RouteDistinguisher) nlriFields[0];
-        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
+    protected DestinationType createWithdrawnDestinationType(final RouteDistinguisher rd,
+            final List<Flowspec> flowspecList, final PathId pathId) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
-                .attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
-                .setDestinationFlowspecL3vpnIpv6(new DestinationFlowspecL3vpnIpv6Builder()
-                    .setRouteDistinguisher(rd)
-                    .setFlowspec(flowspecList)
-                    .setPathId(pathId)
-                    .build()).build();
+            .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
+            .setDestinationFlowspecL3vpnIpv6(new DestinationFlowspecL3vpnIpv6Builder()
+                .setRouteDistinguisher(rd)
+                .setFlowspec(flowspecList)
+                .setPathId(pathId)
+                .build())
+            .build();
     }
 
     @Override