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