2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bgp.flowspec;
10 import static org.junit.Assert.assertArrayEquals;
11 import static org.junit.Assert.assertEquals;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.Mockito.doReturn;
14 import static org.opendaylight.protocol.bgp.flowspec.SimpleFlowspecIpv4NlriParserTest.PATH_ID;
16 import com.google.common.collect.Lists;
17 import com.google.common.collect.Sets;
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.Unpooled;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.Optional;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.mockito.Mock;
26 import org.mockito.MockitoAnnotations;
27 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractNumericOperandParser;
28 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractOperandParser;
29 import org.opendaylight.protocol.bgp.flowspec.handlers.BitmaskOperandParser;
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.FlowspecSubsequentAddressFamily;
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.destination.ipv6.DestinationFlowspecIpv6Builder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.ipv6.route.FlowspecRoute;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.AttributesBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1Builder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2Builder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
69 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
70 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
71 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
72 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
73 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
75 public class SimpleFlowspecIpv6NlriParserTest {
76 private static final NodeIdentifier NEXT_HEADER_NID = new NodeIdentifier(NextHeaders.QNAME);
77 private static final NodeIdentifier FLOW_LABEL_NID = new NodeIdentifier(FlowLabel.QNAME);
80 private PeerSpecificParserConstraint constraint;
82 private MultiPathSupport muliPathSupport;
83 private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
84 private final FlowspecActivator fsa = new FlowspecActivator(this.flowspecContext);
85 private final SimpleFlowspecIpv6NlriParser fsParser = new SimpleFlowspecIpv6NlriParser(
86 this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6,
87 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
89 private static final byte[] REACHED_NLRI = new byte[] {
91 1, 0x28, 0, 1, 2, 3, 4, 5,
92 2, 0x28, 0, 1, 2, 3, 4, 6,
95 private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
98 1, 0x28, 0, 1, 2, 3, 4, 5,
99 2, 0x28, 0, 1, 2, 3, 4, 6,
100 03, (byte) 0x81, 06};
102 private static final byte[] UNREACHED_NLRI = new byte[] {
104 0x0c, (byte) 0x81, 0x0e,
105 0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
108 private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
111 0x0c, (byte) 0x81, 0x0e,
112 0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
116 public void setUp() {
117 MockitoAnnotations.initMocks(this);
118 doReturn(Optional.of(this.muliPathSupport)).when(this.constraint).getPeerConstraint(any());
119 doReturn(true).when(this.muliPathSupport).isTableTypeSupported(any());
123 public void testParseMpReachNlri() throws BGPParsingException {
124 final List<Flowspec> fs = new ArrayList<>();
125 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
127 final FlowspecBuilder builder = new FlowspecBuilder();
128 final DestinationIpv6PrefixCase destinationPrefix = new DestinationIpv6PrefixCaseBuilder()
129 .setDestinationPrefix(new Ipv6Prefix("102:304:500::/40")).build();
130 builder.setFlowspecType(destinationPrefix);
131 fs.add(builder.build());
133 final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(
134 new Ipv6Prefix("102:304:600::/40")).build();
135 builder.setFlowspecType(sourcePrefix);
136 fs.add(builder.build());
138 final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(
139 new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
140 final NextHeaderCase headersCase = new NextHeaderCaseBuilder().setNextHeaders(nextheaders).build();
141 builder.setFlowspecType(headersCase);
142 fs.add(builder.build());
145 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
146 .opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes
147 .destination.type.DestinationFlowspecIpv6CaseBuilder()
148 .setDestinationFlowspecIpv6(
149 new DestinationFlowspecIpv6Builder()
157 final MpReachNlriBuilder result = new MpReachNlriBuilder();
158 result.setAfi(Ipv6AddressFamily.class);
159 result.setSafi(FlowspecSubsequentAddressFamily.class);
160 this.fsParser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result, null);
162 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
163 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type
164 .DestinationFlowspecIpv6Case) result.getAdvertizedRoutes().getDestinationType())
165 .getDestinationFlowspecIpv6().getFlowspec();
166 assertEquals(3, flows.size());
167 assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
168 assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
169 assertEquals(headersCase, flows.get(2).getFlowspecType());
171 final ByteBuf buffer = Unpooled.buffer();
172 this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
173 new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(),
175 assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
177 assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ",
178 this.fsParser.stringNlri(flows));
182 public void testParseMpReachNlriConstraint() throws BGPParsingException {
183 final List<Flowspec> fs = new ArrayList<>();
184 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
186 final FlowspecBuilder builder = new FlowspecBuilder();
187 final DestinationIpv6PrefixCase destinationPrefix = new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(
188 new Ipv6Prefix("102:304:500::/40")).build();
189 builder.setFlowspecType(destinationPrefix);
190 fs.add(builder.build());
192 final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(
193 new Ipv6Prefix("102:304:600::/40")).build();
194 builder.setFlowspecType(sourcePrefix);
195 fs.add(builder.build());
197 final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(
198 new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
199 final NextHeaderCase headersCase = new NextHeaderCaseBuilder().setNextHeaders(nextheaders).build();
200 builder.setFlowspecType(headersCase);
201 fs.add(builder.build());
204 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
205 .opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes
206 .destination.type.DestinationFlowspecIpv6CaseBuilder()
207 .setDestinationFlowspecIpv6(
208 new DestinationFlowspecIpv6Builder()
216 final MpReachNlriBuilder result = new MpReachNlriBuilder();
217 result.setAfi(Ipv6AddressFamily.class);
218 result.setSafi(FlowspecSubsequentAddressFamily.class);
219 this.fsParser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
221 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
222 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type
223 .DestinationFlowspecIpv6Case) result.getAdvertizedRoutes().getDestinationType())
224 .getDestinationFlowspecIpv6().getFlowspec();
225 assertEquals(3, flows.size());
226 assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
227 assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
228 assertEquals(headersCase, flows.get(2).getFlowspecType());
230 final ByteBuf buffer = Unpooled.buffer();
231 this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
232 new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(),
234 assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
236 assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ",
237 this.fsParser.stringNlri(flows));
241 public void testParseMpUnreachNlri() throws BGPParsingException {
242 final List<Flowspec> fs = new ArrayList<>();
243 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
245 final FlowspecBuilder builder = new FlowspecBuilder();
247 final FragmentCase fragment = createFragment();
248 builder.setFlowspecType(fragment);
249 fs.add(builder.build());
251 final FlowspecType label = createLabel();
252 builder.setFlowspecType(label);
253 fs.add(builder.build());
255 mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
256 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
257 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
258 .setDestinationFlowspecIpv6(
259 new DestinationFlowspecIpv6Builder()
266 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
267 result.setAfi(Ipv6AddressFamily.class);
268 result.setSafi(FlowspecSubsequentAddressFamily.class);
269 this.fsParser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result, null);
271 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
272 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
273 .DestinationFlowspecIpv6Case) result.getWithdrawnRoutes().getDestinationType())
274 .getDestinationFlowspecIpv6().getFlowspec();
275 assertEquals(2, flows.size());
276 assertEquals(fragment, flows.get(0).getFlowspecType());
277 assertEquals(label, flows.get(1).getFlowspecType());
279 final ByteBuf buffer = Unpooled.buffer();
280 this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
281 new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
283 assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
285 assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to "
286 + "16777222 or equals to 258 ", this.fsParser.stringNlri(flows));
289 private static FragmentCase createFragment() {
290 final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder().setOp(
291 new BitmaskOperand(false, true, true, false)).setValue(new Fragment(false, true, true, true)).build());
292 return new FragmentCaseBuilder().setFragments(fragments).build();
295 private static FlowspecType createLabel() {
296 final List<FlowLabel> labels = new ArrayList<>(2);
297 labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, false, true, false, false))
298 .setValue(16777222L).build());
299 labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, true, true, false, false))
300 .setValue(258L).build());
301 return new FlowLabelCaseBuilder().setFlowLabel(labels).build();
305 public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
306 final List<Flowspec> fs = new ArrayList<>();
307 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
309 final FlowspecBuilder builder = new FlowspecBuilder();
310 final FragmentCase fragment = createFragment();
312 builder.setFlowspecType(fragment);
313 fs.add(builder.build());
315 final FlowspecType label = createLabel();
316 builder.setFlowspecType(label);
317 fs.add(builder.build());
319 mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
320 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
321 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
322 .setDestinationFlowspecIpv6(
323 new DestinationFlowspecIpv6Builder()
331 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
332 result.setAfi(Ipv6AddressFamily.class);
333 result.setSafi(FlowspecSubsequentAddressFamily.class);
334 this.fsParser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
336 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
337 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
338 .DestinationFlowspecIpv6Case) result.getWithdrawnRoutes().getDestinationType())
339 .getDestinationFlowspecIpv6().getFlowspec();
340 assertEquals(2, flows.size());
341 assertEquals(fragment, flows.get(0).getFlowspecType());
342 assertEquals(label, flows.get(1).getFlowspecType());
344 final ByteBuf buffer = Unpooled.buffer();
345 this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
346 new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
348 assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
350 assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to "
351 + "16777222 or equals to 258 ", this.fsParser.stringNlri(flows));
355 public void testExtractFlowspecFragments() {
356 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
357 Builders.mapEntryBuilder();
358 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
359 entry.withChild(Builders.unkeyedListBuilder()
360 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
361 .withChild(Builders.unkeyedListEntryBuilder()
362 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
363 .withChild(Builders.choiceBuilder()
364 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
365 .withChild(Builders.unkeyedListBuilder()
366 .withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
367 .withChild(Builders.unkeyedListEntryBuilder()
368 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
369 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
370 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
371 AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE,
372 BitmaskOperandParser.NOT_VALUE)).build())
373 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
374 .withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE,
375 AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE,
376 AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
377 .build()).build()).build()).build());
378 final FlowspecBuilder expectedFS = new FlowspecBuilder();
379 expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder()
380 .setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build()))
382 final List<Flowspec> expectedValue = new ArrayList<>();
383 expectedValue.add(expectedFS.build());
384 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
388 public void testExtractFlowspecNextHeaders() {
389 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
390 Builders.mapEntryBuilder();
391 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
392 entry.withChild(Builders.unkeyedListBuilder()
393 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
394 .withChild(Builders.unkeyedListEntryBuilder()
395 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
396 .withChild(Builders.choiceBuilder()
397 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
398 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(NEXT_HEADER_NID)
399 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
400 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
401 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
402 AbstractOperandParser.AND_BIT_VALUE)).build())
403 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
404 .withValue((short) 100).build()).build())
405 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
406 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
407 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
408 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
409 .withValue((short) 200).build()).build())
410 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
411 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
412 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
413 AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE))
415 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
416 .withValue((short) 210).build()).build())
417 .build()).build()).build()).build());
419 final FlowspecBuilder expectedFS = new FlowspecBuilder();
420 expectedFS.setFlowspecType(new NextHeaderCaseBuilder().setNextHeaders(Lists.newArrayList(
421 new NextHeadersBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false))
423 new NextHeadersBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false))
425 new NextHeadersBuilder().setValue((short) 210).setOp(new NumericOperand(true, true, true, false, false))
427 final List<Flowspec> expectedValue = new ArrayList<>();
428 expectedValue.add(expectedFS.build());
429 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
433 public void testExtractFlowspecFlowLabels() {
434 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
435 Builders.mapEntryBuilder();
436 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
437 entry.withChild(Builders.unkeyedListBuilder()
438 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
439 .withChild(Builders.unkeyedListEntryBuilder()
440 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
441 .withChild(Builders.choiceBuilder()
442 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
443 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FLOW_LABEL_NID)
444 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
445 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
446 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
447 AbstractOperandParser.AND_BIT_VALUE)).build())
448 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
449 .withValue(100L).build()).build())
450 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
451 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
452 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
453 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
454 .withValue(200L).build()).build())
455 .build()).build()).build()).build());
457 final FlowspecBuilder expectedFS = new FlowspecBuilder();
458 expectedFS.setFlowspecType(new FlowLabelCaseBuilder().setFlowLabel(Lists.newArrayList(
459 new FlowLabelBuilder().setValue(100L).setOp(new NumericOperand(true, true, false, false, false)).build(),
460 new FlowLabelBuilder().setValue(200L).setOp(new NumericOperand(true, false, false, false, false)).build()))
462 final List<Flowspec> expectedValue = new ArrayList<>();
463 expectedValue.add(expectedFS.build());
464 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
468 public void testExtractFlowspecDestPrefix() {
469 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
470 Builders.mapEntryBuilder();
471 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
472 entry.withChild(Builders.unkeyedListBuilder()
473 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
474 .withChild(Builders.unkeyedListEntryBuilder()
475 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
476 .withChild(Builders.choiceBuilder()
477 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
478 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID)
479 .withValue("102:304:500::/40").build()).build()).build()).build());
480 final FlowspecBuilder expectedFS = new FlowspecBuilder();
481 expectedFS.setFlowspecType(new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(
482 new Ipv6Prefix("102:304:500::/40")).build());
483 final List<Flowspec> expectedValue = new ArrayList<>();
484 expectedValue.add(expectedFS.build());
485 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
489 public void testExtractFlowspecSourcePrefix() {
490 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
491 Builders.mapEntryBuilder();
492 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
493 entry.withChild(Builders.unkeyedListBuilder()
494 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
495 .withChild(Builders.unkeyedListEntryBuilder()
496 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
497 .withChild(Builders.choiceBuilder()
498 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
499 .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.SOURCE_PREFIX_NID)
500 .withValue("102:304:600::/40").build()).build()).build()).build());
501 final FlowspecBuilder expectedFS = new FlowspecBuilder();
502 expectedFS.setFlowspecType(new SourceIpv6PrefixCaseBuilder().setSourcePrefix(
503 new Ipv6Prefix("102:304:600::/40")).build());
504 final List<Flowspec> expectedValue = new ArrayList<>();
505 expectedValue.add(expectedFS.build());
506 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));