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