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