a3cb22f2fc6a0ff5ffe5cfa9e1933b37e32959fd
[bgpcep.git] / bgp / extensions / flowspec / src / test / java / org / opendaylight / protocol / bgp / flowspec / SimpleFlowspecIpv6NlriParserTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.protocol.bgp.flowspec;
9
10 import static org.junit.Assert.assertArrayEquals;
11 import static org.junit.Assert.assertEquals;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.Mockito.doReturn;
14 import static org.opendaylight.protocol.bgp.flowspec.SimpleFlowspecIpv4NlriParserTest.PATH_ID;
15
16 import com.google.common.collect.Lists;
17 import com.google.common.collect.Sets;
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.Unpooled;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.Optional;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.mockito.Mock;
26 import org.mockito.MockitoAnnotations;
27 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractNumericOperandParser;
28 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractOperandParser;
29 import org.opendaylight.protocol.bgp.flowspec.handlers.BitmaskOperandParser;
30 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
31 import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupport;
32 import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
33 import org.opendaylight.protocol.util.ByteArray;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.BitmaskOperand;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.FlowspecSubsequentAddressFamily;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.Fragment;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.NumericOperand;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.Flowspec;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.FlowspecBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.FlowspecType;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.FragmentCase;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.fragment._case.Fragments;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.fragment._case.FragmentsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.FlowLabelCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabel;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabelBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeaders;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeadersBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.ipv6.DestinationFlowspecIpv6Builder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.ipv6.route.FlowspecRoute;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.AttributesBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1Builder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2Builder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
69 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
70 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
71 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
72 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
73 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
74
75 public class SimpleFlowspecIpv6NlriParserTest {
76     private static final NodeIdentifier NEXT_HEADER_NID = new NodeIdentifier(NextHeaders.QNAME);
77     private static final NodeIdentifier FLOW_LABEL_NID = new NodeIdentifier(FlowLabel.QNAME);
78
79     @Mock
80     private PeerSpecificParserConstraint constraint;
81     @Mock
82     private MultiPathSupport muliPathSupport;
83     private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
84     private final FlowspecActivator fsa = new FlowspecActivator(this.flowspecContext);
85     private final SimpleFlowspecIpv6NlriParser fsParser = new SimpleFlowspecIpv6NlriParser(
86         this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6,
87             SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
88
89     private static final byte[] REACHED_NLRI = new byte[] {
90         0x13,
91         1, 0x28, 0, 1, 2, 3, 4, 5,
92         2, 0x28, 0, 1, 2, 3, 4, 6,
93         03, (byte) 0x81, 06};
94
95     private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
96         0x0, 0x0, 0x0, 0x1,
97         0x13,
98         1, 0x28, 0, 1, 2, 3, 4, 5,
99         2, 0x28, 0, 1, 2, 3, 4, 6,
100         03, (byte) 0x81, 06};
101
102     private static final byte[] UNREACHED_NLRI = new byte[] {
103         0x0c,
104         0x0c, (byte) 0x81, 0x0e,
105         0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
106     };
107
108     private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
109         0x0, 0x0, 0x0, 0x1,
110         0x0c,
111         0x0c, (byte) 0x81, 0x0e,
112         0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
113     };
114
115     @Before
116     public void setUp() {
117         MockitoAnnotations.initMocks(this);
118         doReturn(Optional.of(this.muliPathSupport)).when(this.constraint).getPeerConstraint(any());
119         doReturn(true).when(this.muliPathSupport).isTableTypeSupported(any());
120     }
121
122     @Test
123     public void testParseMpReachNlri() throws BGPParsingException {
124         final List<Flowspec> fs = new ArrayList<>();
125         final MpReachNlriBuilder mp = new MpReachNlriBuilder();
126
127         final FlowspecBuilder builder = new FlowspecBuilder();
128         final DestinationIpv6PrefixCase destinationPrefix = new DestinationIpv6PrefixCaseBuilder()
129                 .setDestinationPrefix(new Ipv6Prefix("102:304:500::/40")).build();
130         builder.setFlowspecType(destinationPrefix);
131         fs.add(builder.build());
132
133         final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(
134             new Ipv6Prefix("102:304:600::/40")).build();
135         builder.setFlowspecType(sourcePrefix);
136         fs.add(builder.build());
137
138         final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(
139             new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
140         final NextHeaderCase headersCase = new NextHeaderCaseBuilder().setNextHeaders(nextheaders).build();
141         builder.setFlowspecType(headersCase);
142         fs.add(builder.build());
143
144
145         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
146             .opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes
147             .destination.type.DestinationFlowspecIpv6CaseBuilder()
148                 .setDestinationFlowspecIpv6(
149                     new DestinationFlowspecIpv6Builder()
150                         .setFlowspec(fs)
151                         .build()
152                 )
153                 .build()
154             ).build()
155         );
156
157         final MpReachNlriBuilder result = new MpReachNlriBuilder();
158         result.setAfi(Ipv6AddressFamily.class);
159         result.setSafi(FlowspecSubsequentAddressFamily.class);
160         this.fsParser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result, null);
161
162         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
163                 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type
164                 .DestinationFlowspecIpv6Case) result.getAdvertizedRoutes().getDestinationType())
165                 .getDestinationFlowspecIpv6().getFlowspec();
166         assertEquals(3, flows.size());
167         assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
168         assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
169         assertEquals(headersCase, flows.get(2).getFlowspecType());
170
171         final ByteBuf buffer = Unpooled.buffer();
172         this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
173             new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(),
174             buffer);
175         assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
176
177         assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ",
178             this.fsParser.stringNlri(flows));
179     }
180
181     @Test
182     public void testParseMpReachNlriConstraint() throws BGPParsingException {
183         final List<Flowspec> fs = new ArrayList<>();
184         final MpReachNlriBuilder mp = new MpReachNlriBuilder();
185
186         final FlowspecBuilder builder = new FlowspecBuilder();
187         final DestinationIpv6PrefixCase destinationPrefix = new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(
188             new Ipv6Prefix("102:304:500::/40")).build();
189         builder.setFlowspecType(destinationPrefix);
190         fs.add(builder.build());
191
192         final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(
193             new Ipv6Prefix("102:304:600::/40")).build();
194         builder.setFlowspecType(sourcePrefix);
195         fs.add(builder.build());
196
197         final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(
198             new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
199         final NextHeaderCase headersCase = new NextHeaderCaseBuilder().setNextHeaders(nextheaders).build();
200         builder.setFlowspecType(headersCase);
201         fs.add(builder.build());
202
203
204         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
205             .opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes
206             .destination.type.DestinationFlowspecIpv6CaseBuilder()
207                 .setDestinationFlowspecIpv6(
208                     new DestinationFlowspecIpv6Builder()
209                         .setPathId(PATH_ID)
210                         .setFlowspec(fs)
211                         .build()
212                 ).build()
213             ).build()
214         );
215
216         final MpReachNlriBuilder result = new MpReachNlriBuilder();
217         result.setAfi(Ipv6AddressFamily.class);
218         result.setSafi(FlowspecSubsequentAddressFamily.class);
219         this.fsParser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
220
221         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
222                 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type
223                 .DestinationFlowspecIpv6Case) result.getAdvertizedRoutes().getDestinationType())
224                 .getDestinationFlowspecIpv6().getFlowspec();
225         assertEquals(3, flows.size());
226         assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
227         assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
228         assertEquals(headersCase, flows.get(2).getFlowspecType());
229
230         final ByteBuf buffer = Unpooled.buffer();
231         this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
232             new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(),
233             buffer);
234         assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
235
236         assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ",
237             this.fsParser.stringNlri(flows));
238     }
239
240     @Test
241     public void testParseMpUnreachNlri() throws BGPParsingException {
242         final List<Flowspec> fs = new ArrayList<>();
243         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
244
245         final FlowspecBuilder builder = new FlowspecBuilder();
246
247         final FragmentCase fragment = createFragment();
248         builder.setFlowspecType(fragment);
249         fs.add(builder.build());
250
251         final FlowspecType label = createLabel();
252         builder.setFlowspecType(label);
253         fs.add(builder.build());
254
255         mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
256             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
257             .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
258                 .setDestinationFlowspecIpv6(
259                     new DestinationFlowspecIpv6Builder()
260                         .setFlowspec(fs)
261                         .build()
262                 ).build()
263             ).build()
264         );
265
266         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
267         result.setAfi(Ipv6AddressFamily.class);
268         result.setSafi(FlowspecSubsequentAddressFamily.class);
269         this.fsParser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result, null);
270
271         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
272                 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
273                 .DestinationFlowspecIpv6Case) result.getWithdrawnRoutes().getDestinationType())
274                 .getDestinationFlowspecIpv6().getFlowspec();
275         assertEquals(2, flows.size());
276         assertEquals(fragment, flows.get(0).getFlowspecType());
277         assertEquals(label, flows.get(1).getFlowspecType());
278
279         final ByteBuf buffer = Unpooled.buffer();
280         this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
281             new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
282
283         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
284
285         assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to "
286                 + "16777222 or equals to 258 ", this.fsParser.stringNlri(flows));
287     }
288
289     private static FragmentCase createFragment() {
290         final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder().setOp(
291             new BitmaskOperand(false, true, true, false)).setValue(new Fragment(false, true, true, true)).build());
292         return new FragmentCaseBuilder().setFragments(fragments).build();
293     }
294
295     private static FlowspecType createLabel() {
296         final List<FlowLabel> labels = new ArrayList<>(2);
297         labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, false, true, false, false))
298             .setValue(16777222L).build());
299         labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, true, true, false, false))
300             .setValue(258L).build());
301         return new FlowLabelCaseBuilder().setFlowLabel(labels).build();
302     }
303
304     @Test
305     public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
306         final List<Flowspec> fs = new ArrayList<>();
307         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
308
309         final FlowspecBuilder builder = new FlowspecBuilder();
310         final FragmentCase fragment = createFragment();
311
312         builder.setFlowspecType(fragment);
313         fs.add(builder.build());
314
315         final FlowspecType label = createLabel();
316         builder.setFlowspecType(label);
317         fs.add(builder.build());
318
319         mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
320             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
321             .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
322                 .setDestinationFlowspecIpv6(
323                     new DestinationFlowspecIpv6Builder()
324                         .setPathId(PATH_ID)
325                         .setFlowspec(fs)
326                         .build()
327                 ).build()
328             ).build()
329         );
330
331         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
332         result.setAfi(Ipv6AddressFamily.class);
333         result.setSafi(FlowspecSubsequentAddressFamily.class);
334         this.fsParser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
335
336         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
337                 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
338                 .DestinationFlowspecIpv6Case) result.getWithdrawnRoutes().getDestinationType())
339                 .getDestinationFlowspecIpv6().getFlowspec();
340         assertEquals(2, flows.size());
341         assertEquals(fragment, flows.get(0).getFlowspecType());
342         assertEquals(label, flows.get(1).getFlowspecType());
343
344         final ByteBuf buffer = Unpooled.buffer();
345         this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
346             new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
347
348         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
349
350         assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to "
351                 + "16777222 or equals to 258 ", this.fsParser.stringNlri(flows));
352     }
353
354     @Test
355     public void testExtractFlowspecFragments() {
356         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
357                 Builders.mapEntryBuilder();
358         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
359         entry.withChild(Builders.unkeyedListBuilder()
360             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
361             .withChild(Builders.unkeyedListEntryBuilder()
362                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
363                 .withChild(Builders.choiceBuilder()
364                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
365                     .withChild(Builders.unkeyedListBuilder()
366                         .withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
367                         .withChild(Builders.unkeyedListEntryBuilder()
368                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
369                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
370                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
371                                     AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE,
372                                     BitmaskOperandParser.NOT_VALUE)).build())
373                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
374                                 .withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE,
375                                     AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE,
376                                     AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
377                         .build()).build()).build()).build());
378         final FlowspecBuilder expectedFS = new FlowspecBuilder();
379         expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder()
380             .setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build()))
381             .build());
382         final List<Flowspec> expectedValue = new ArrayList<>();
383         expectedValue.add(expectedFS.build());
384         assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
385     }
386
387     @Test
388     public void testExtractFlowspecNextHeaders() {
389         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
390                 Builders.mapEntryBuilder();
391         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
392         entry.withChild(Builders.unkeyedListBuilder()
393             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
394             .withChild(Builders.unkeyedListEntryBuilder()
395                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
396                 .withChild(Builders.choiceBuilder()
397                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
398                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(NEXT_HEADER_NID)
399                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
400                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
401                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
402                                     AbstractOperandParser.AND_BIT_VALUE)).build())
403                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
404                                 .withValue((short) 100).build()).build())
405                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
406                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
407                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
408                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
409                                 .withValue((short) 200).build()).build())
410                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
411                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
412                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
413                                     AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE))
414                                 .build())
415                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
416                                 .withValue((short) 210).build()).build())
417                         .build()).build()).build()).build());
418
419         final FlowspecBuilder expectedFS = new FlowspecBuilder();
420         expectedFS.setFlowspecType(new NextHeaderCaseBuilder().setNextHeaders(Lists.newArrayList(
421             new NextHeadersBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false))
422             .build(),
423             new NextHeadersBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false))
424             .build(),
425             new NextHeadersBuilder().setValue((short) 210).setOp(new NumericOperand(true, true, true, false, false))
426             .build())).build());
427         final List<Flowspec> expectedValue = new ArrayList<>();
428         expectedValue.add(expectedFS.build());
429         assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
430     }
431
432     @Test
433     public void testExtractFlowspecFlowLabels() {
434         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
435                 Builders.mapEntryBuilder();
436         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
437         entry.withChild(Builders.unkeyedListBuilder()
438             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
439             .withChild(Builders.unkeyedListEntryBuilder()
440                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
441                 .withChild(Builders.choiceBuilder()
442                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
443                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FLOW_LABEL_NID)
444                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
445                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
446                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
447                                     AbstractOperandParser.AND_BIT_VALUE)).build())
448                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
449                                 .withValue(100L).build()).build())
450                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
451                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
452                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
453                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
454                                 .withValue(200L).build()).build())
455                         .build()).build()).build()).build());
456
457         final FlowspecBuilder expectedFS = new FlowspecBuilder();
458         expectedFS.setFlowspecType(new FlowLabelCaseBuilder().setFlowLabel(Lists.newArrayList(
459             new FlowLabelBuilder().setValue(100L).setOp(new NumericOperand(true, true, false, false, false)).build(),
460             new FlowLabelBuilder().setValue(200L).setOp(new NumericOperand(true, false, false, false, false)).build()))
461             .build());
462         final List<Flowspec> expectedValue = new ArrayList<>();
463         expectedValue.add(expectedFS.build());
464         assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
465     }
466
467     @Test
468     public void testExtractFlowspecDestPrefix() {
469         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
470                 Builders.mapEntryBuilder();
471         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
472         entry.withChild(Builders.unkeyedListBuilder()
473             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
474             .withChild(Builders.unkeyedListEntryBuilder()
475                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
476                 .withChild(Builders.choiceBuilder()
477                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
478                     .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID)
479                         .withValue("102:304:500::/40").build()).build()).build()).build());
480         final FlowspecBuilder expectedFS = new FlowspecBuilder();
481         expectedFS.setFlowspecType(new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(
482             new Ipv6Prefix("102:304:500::/40")).build());
483         final List<Flowspec> expectedValue = new ArrayList<>();
484         expectedValue.add(expectedFS.build());
485         assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
486     }
487
488     @Test
489     public void testExtractFlowspecSourcePrefix() {
490         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
491                 Builders.mapEntryBuilder();
492         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
493         entry.withChild(Builders.unkeyedListBuilder()
494             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
495             .withChild(Builders.unkeyedListEntryBuilder()
496                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
497                 .withChild(Builders.choiceBuilder()
498                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
499                     .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.SOURCE_PREFIX_NID)
500                         .withValue("102:304:600::/40").build()).build()).build()).build());
501         final FlowspecBuilder expectedFS = new FlowspecBuilder();
502         expectedFS.setFlowspecType(new SourceIpv6PrefixCaseBuilder().setSourcePrefix(
503             new Ipv6Prefix("102:304:600::/40")).build());
504         final List<Flowspec> expectedValue = new ArrayList<>();
505         expectedValue.add(expectedFS.build());
506         assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
507     }
508 }
509