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