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