40cb5bd1fb44643e53f7b57e0ad2dd2c4d9991d2
[bgpcep.git] / bgp / 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.rev150807.BitmaskOperand;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecL3vpnSubsequentAddressFamily;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.Fragment;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.NumericOperand;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.FragmentCase;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.fragment._case.Fragments;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.fragment._case.FragmentsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.FlowLabelCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.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.rev150807.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.rev150807.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.rev150807.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.rev150807.flowspec.ipv6.route.FlowspecRoute;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv6.DestinationFlowspecL3vpnIpv6;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv6.DestinationFlowspecL3vpnIpv6Builder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1Builder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2Builder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.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.DataContainerNodeAttrBuilder;
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 FS_PARSER = new FlowspecL3vpnIpv6NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
90
91     private static final byte[] REACHED_NLRI = new byte[]{
92         0x1B,   // NLRI length: 19+8=27
93         0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
94         1, 0x28, 0, 1, 2, 3, 4, 5,
95         2, 0x28, 0, 1, 2, 3, 4, 6,
96         03, (byte) 0x81, 06};
97
98     private static final byte[] REACHED_NLRI_ADD_PATH = new byte[]{
99         0x0, 0x0, 0x0, 0x1,
100         0x1B,
101         0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
102         1, 0x28, 0, 1, 2, 3, 4, 5,
103         2, 0x28, 0, 1, 2, 3, 4, 6,
104         03, (byte) 0x81, 06};
105
106     private static final byte[] UNREACHED_NLRI = new byte[]{
107         0x14,   // NLRI length: 12+8=20
108         0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
109         0x0c, (byte) 0x81, 0x0e,
110         0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
111     };
112
113     private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[]{
114         0x0, 0x0, 0x0, 0x1,
115         0x14,   // NLRI length: 12+8=20
116         0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
117         0x0c, (byte) 0x81, 0x0e,
118         0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
119     };
120
121     @Before
122     public void setUp() {
123         MockitoAnnotations.initMocks(this);
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(new Ipv6Prefix("102:304:500::/40")).build();
135         builder.setFlowspecType(destinationPrefix);
136         fs.add(builder.build());
137
138         final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(new Ipv6Prefix("102:304:600::/40")).build();
139         builder.setFlowspecType(sourcePrefix);
140         fs.add(builder.build());
141
142         final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
143         final NextHeaderCase headersCase = new NextHeaderCaseBuilder().setNextHeaders(nextheaders).build();
144         builder.setFlowspecType(headersCase);
145         fs.add(builder.build());
146
147         final MpReachNlriBuilder result = new MpReachNlriBuilder();
148         result.setAfi(Ipv6AddressFamily.class);
149         result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
150         this.FS_PARSER.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result);
151
152         DestinationFlowspecL3vpnIpv6 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) result.getAdvertizedRoutes().getDestinationType())
153             .getDestinationFlowspecL3vpnIpv6();
154         final List<Flowspec> flows = flowspecDst.getFlowspec();
155
156         final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
157
158         assertEquals(3, flows.size());
159         assertEquals(ROUTE_DISTINGUISHER, new String(rd.getValue()));
160         assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
161         assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
162         assertEquals(headersCase, flows.get(2).getFlowspecType());
163
164         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
165             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
166                 .setDestinationFlowspecL3vpnIpv6(
167                     new DestinationFlowspecL3vpnIpv6Builder()
168                         .setRouteDistinguisher(rd)
169                         .setFlowspec(fs)
170                         .build()
171                 )
172                 .build()
173             ).build()
174         );
175
176         final ByteBuf buffer = Unpooled.buffer();
177         this.FS_PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(), buffer);
178         assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
179
180         assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ", this.FS_PARSER.stringNlri(flows));
181     }
182
183     @Test
184     public void testParseMpReachNlriConstraint() throws BGPParsingException {
185         final List<Flowspec> fs = new ArrayList<>();
186         final MpReachNlriBuilder mp = new MpReachNlriBuilder();
187
188         final FlowspecBuilder builder = new FlowspecBuilder();
189         final DestinationIpv6PrefixCase destinationPrefix = new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(new Ipv6Prefix("102:304:500::/40")).build();
190         builder.setFlowspecType(destinationPrefix);
191         fs.add(builder.build());
192
193         final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(new Ipv6Prefix("102:304:600::/40")).build();
194         builder.setFlowspecType(sourcePrefix);
195         fs.add(builder.build());
196
197         final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
198         final NextHeaderCase headersCase = new NextHeaderCaseBuilder().setNextHeaders(nextheaders).build();
199         builder.setFlowspecType(headersCase);
200         fs.add(builder.build());
201
202         final MpReachNlriBuilder result = new MpReachNlriBuilder();
203         result.setAfi(Ipv6AddressFamily.class);
204         result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
205         this.FS_PARSER.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
206
207         final DestinationFlowspecL3vpnIpv6 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) result.getAdvertizedRoutes().getDestinationType())
208             .getDestinationFlowspecL3vpnIpv6();
209         final List<Flowspec> flows = flowspecDst.getFlowspec();
210         final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
211
212         assertEquals(3, flows.size());
213         assertEquals(ROUTE_DISTINGUISHER, new String(rd.getValue()));
214         assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
215         assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
216         assertEquals(headersCase, flows.get(2).getFlowspecType());
217
218         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
219             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
220                 .setDestinationFlowspecL3vpnIpv6(
221                     new DestinationFlowspecL3vpnIpv6Builder()
222                         .setPathId(PATH_ID)
223                         .setRouteDistinguisher(rd)
224                         .setFlowspec(fs)
225                         .build()
226                 ).build()
227             ).build()
228         );
229
230         final ByteBuf buffer = Unpooled.buffer();
231         this.FS_PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(), buffer);
232         assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
233
234         assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ", this.FS_PARSER.stringNlri(flows));
235     }
236
237     @Test
238     public void testParseMpUnreachNlri() throws BGPParsingException {
239         final List<Flowspec> fs = new ArrayList<>();
240         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
241
242         final FlowspecBuilder builder = new FlowspecBuilder();
243
244         final FragmentCase fragment = createFragment();
245         builder.setFlowspecType(fragment);
246         fs.add(builder.build());
247
248         final FlowspecType label = createLabel();
249         builder.setFlowspecType(label);
250         fs.add(builder.build());
251
252         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
253         result.setAfi(Ipv6AddressFamily.class);
254         result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
255         this.FS_PARSER.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result);
256
257         final DestinationFlowspecL3vpnIpv6 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) result.getWithdrawnRoutes().getDestinationType())
258             .getDestinationFlowspecL3vpnIpv6();
259         final List<Flowspec> flows = flowspecDst.getFlowspec();
260         final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
261
262         assertEquals(2, flows.size());
263         assertEquals(ROUTE_DISTINGUISHER, new String(rd.getValue()));
264         assertEquals(fragment, flows.get(0).getFlowspecType());
265         assertEquals(label, flows.get(1).getFlowspecType());
266
267         mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
268             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
269                 .setDestinationFlowspecL3vpnIpv6(
270                     new DestinationFlowspecL3vpnIpv6Builder()
271                         .setRouteDistinguisher(rd)
272                         .setFlowspec(fs)
273                         .build()
274                 ).build()
275             ).build()
276         );
277
278         final ByteBuf buffer = Unpooled.buffer();
279         this.FS_PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
280
281         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
282
283         assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to 16777222 or equals to 258 ", this.FS_PARSER.stringNlri(flows));
284     }
285
286     private static FragmentCase createFragment() {
287         final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(new Fragment(false, true, true, true)).build());
288         return new FragmentCaseBuilder().setFragments(fragments).build();
289     }
290
291     private static FlowspecType createLabel() {
292         final List<FlowLabel> labels = new ArrayList<>(2);
293         labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, false, true, false, false)).setValue(new Long(16777222L)).build());
294         labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(new Long(258L)).build());
295         return new FlowLabelCaseBuilder().setFlowLabel(labels).build();
296     }
297
298     @Test
299     public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
300         final List<Flowspec> fs = new ArrayList<>();
301         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
302
303         final FlowspecBuilder builder = new FlowspecBuilder();
304         final FragmentCase fragment = createFragment();
305
306         builder.setFlowspecType(fragment);
307         fs.add(builder.build());
308
309         final FlowspecType label = createLabel();
310         builder.setFlowspecType(label);
311         fs.add(builder.build());
312
313         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
314         result.setAfi(Ipv6AddressFamily.class);
315         result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
316         this.FS_PARSER.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
317
318         final DestinationFlowspecL3vpnIpv6 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) result.getWithdrawnRoutes().getDestinationType())
319             .getDestinationFlowspecL3vpnIpv6();
320         final List<Flowspec> flows = flowspecDst.getFlowspec();
321         final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
322
323         assertEquals(2, flows.size());
324         assertEquals(ROUTE_DISTINGUISHER, new String(rd.getValue()));
325         assertEquals(fragment, flows.get(0).getFlowspecType());
326         assertEquals(label, flows.get(1).getFlowspecType());
327
328         mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
329             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
330                 .setDestinationFlowspecL3vpnIpv6(
331                     new DestinationFlowspecL3vpnIpv6Builder()
332                         .setRouteDistinguisher(rd)
333                         .setPathId(PATH_ID)
334                         .setFlowspec(fs)
335                         .build()
336                 ).build()
337             ).build()
338         );
339
340         final ByteBuf buffer = Unpooled.buffer();
341         this.FS_PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
342
343         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
344
345         assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to 16777222 or equals to 258 ", this.FS_PARSER.stringNlri(flows));
346     }
347
348     @Test
349     public void testExtractFlowspecFragments() {
350         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
351         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
352         entry.withChild(Builders.unkeyedListBuilder()
353             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
354             .withChild(Builders.unkeyedListEntryBuilder()
355                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
356                 .withChild(Builders.choiceBuilder()
357                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
358                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
359                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID)
360                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)).build())
361                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE, AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE, AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
362                         .build()).build()).build()).build());
363         final FlowspecBuilder expectedFS = new FlowspecBuilder();
364         expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build());
365         final List<Flowspec> expectedValue = new ArrayList<>();
366         expectedValue.add(expectedFS.build());
367         assertEquals(expectedValue, this.FS_PARSER.extractFlowspec(entry.build()));
368     }
369
370     @Test
371     public void testExtractFlowspecNextHeaders() {
372         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
373         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
374         entry.withChild(Builders.unkeyedListBuilder()
375             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
376             .withChild(Builders.unkeyedListEntryBuilder()
377                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
378                 .withChild(Builders.choiceBuilder()
379                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
380                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(NEXT_HEADER_NID)
381                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
382                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
383                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue((short) 100).build()).build())
384                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
385                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
386                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue((short) 200).build()).build())
387                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
388                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
389                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue((short) 210).build()).build())
390                         .build()).build()).build()).build());
391
392         final FlowspecBuilder expectedFS = new FlowspecBuilder();
393         expectedFS.setFlowspecType(new NextHeaderCaseBuilder().setNextHeaders(Lists.newArrayList(
394             new NextHeadersBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false)).build(),
395             new NextHeadersBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false)).build(),
396             new NextHeadersBuilder().setValue((short) 210).setOp(new NumericOperand(true, true, true, false, false)).build())).build());
397         final List<Flowspec> expectedValue = new ArrayList<>();
398         expectedValue.add(expectedFS.build());
399         assertEquals(expectedValue, this.FS_PARSER.extractFlowspec(entry.build()));
400     }
401
402     @Test
403     public void testExtractFlowspecFlowLabels() {
404         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
405         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
406         entry.withChild(Builders.unkeyedListBuilder()
407             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
408             .withChild(Builders.unkeyedListEntryBuilder()
409                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
410                 .withChild(Builders.choiceBuilder()
411                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
412                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FLOW_LABEL_NID)
413                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
414                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
415                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue(100L).build()).build())
416                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
417                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
418                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue(200L).build()).build())
419                         .build()).build()).build()).build());
420
421         final FlowspecBuilder expectedFS = new FlowspecBuilder();
422         expectedFS.setFlowspecType(new FlowLabelCaseBuilder().setFlowLabel(Lists.newArrayList(
423             new FlowLabelBuilder().setValue(100L).setOp(new NumericOperand(true, true, false, false, false)).build(),
424             new FlowLabelBuilder().setValue(200L).setOp(new NumericOperand(true, false, false, false, false)).build())).build());
425         final List<Flowspec> expectedValue = new ArrayList<>();
426         expectedValue.add(expectedFS.build());
427         assertEquals(expectedValue, this.FS_PARSER.extractFlowspec(entry.build()));
428     }
429
430     @Test
431     public void testExtractFlowspecDestPrefix() {
432         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
433         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
434         entry.withChild(Builders.unkeyedListBuilder()
435             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
436             .withChild(Builders.unkeyedListEntryBuilder()
437                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
438                 .withChild(Builders.choiceBuilder()
439                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
440                     .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.DEST_PREFIX_NID).withValue("102:304:500::/40").build()).build()).build()).build());
441         final FlowspecBuilder expectedFS = new FlowspecBuilder();
442         expectedFS.setFlowspecType(new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(new Ipv6Prefix("102:304:500::/40")).build());
443         final List<Flowspec> expectedValue = new ArrayList<>();
444         expectedValue.add(expectedFS.build());
445         assertEquals(expectedValue, this.FS_PARSER.extractFlowspec(entry.build()));
446     }
447
448     @Test
449     public void testExtractFlowspecSourcePrefix() {
450         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
451         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
452         entry.withChild(Builders.unkeyedListBuilder()
453             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
454             .withChild(Builders.unkeyedListEntryBuilder()
455                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
456                 .withChild(Builders.choiceBuilder()
457                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
458                     .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.SOURCE_PREFIX_NID).withValue("102:304:600::/40").build()).build()).build()).build());
459         final FlowspecBuilder expectedFS = new FlowspecBuilder();
460         expectedFS.setFlowspecType(new SourceIpv6PrefixCaseBuilder().setSourcePrefix(new Ipv6Prefix("102:304:600::/40")).build());
461         final List<Flowspec> expectedValue = new ArrayList<>();
462         expectedValue.add(expectedFS.build());
463         assertEquals(expectedValue, this.FS_PARSER.extractFlowspec(entry.build()));
464     }
465 }
466