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.common.Uint32;
70 import org.opendaylight.yangtools.yang.common.Uint8;
71 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
72 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
73 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
74 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
75 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
77 public class SimpleFlowspecIpv6NlriParserTest {
78 private static final NodeIdentifier NEXT_HEADER_NID = new NodeIdentifier(NextHeaders.QNAME);
79 private static final NodeIdentifier FLOW_LABEL_NID = new NodeIdentifier(FlowLabel.QNAME);
82 private PeerSpecificParserConstraint constraint;
84 private MultiPathSupport muliPathSupport;
85 private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
86 private final FlowspecActivator fsa = new FlowspecActivator(this.flowspecContext);
87 private final SimpleFlowspecIpv6NlriParser fsParser = new SimpleFlowspecIpv6NlriParser(
88 this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6,
89 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
91 private static final byte[] REACHED_NLRI = new byte[] {
93 1, 0x28, 0, 1, 2, 3, 4, 5,
94 2, 0x28, 0, 1, 2, 3, 4, 6,
97 private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
100 1, 0x28, 0, 1, 2, 3, 4, 5,
101 2, 0x28, 0, 1, 2, 3, 4, 6,
102 03, (byte) 0x81, 06};
104 private static final byte[] UNREACHED_NLRI = new byte[] {
106 0x0c, (byte) 0x81, 0x0e,
107 0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
110 private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
113 0x0c, (byte) 0x81, 0x0e,
114 0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
118 public void setUp() {
119 MockitoAnnotations.initMocks(this);
120 doReturn(Optional.of(this.muliPathSupport)).when(this.constraint).getPeerConstraint(any());
121 doReturn(true).when(this.muliPathSupport).isTableTypeSupported(any());
125 public void testParseMpReachNlri() throws BGPParsingException {
126 final List<Flowspec> fs = new ArrayList<>();
127 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
129 final FlowspecBuilder builder = new FlowspecBuilder();
130 final DestinationIpv6PrefixCase destinationPrefix = new DestinationIpv6PrefixCaseBuilder()
131 .setDestinationPrefix(new Ipv6Prefix("102:304:500::/40")).build();
132 builder.setFlowspecType(destinationPrefix);
133 fs.add(builder.build());
135 final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(
136 new Ipv6Prefix("102:304:600::/40")).build();
137 builder.setFlowspecType(sourcePrefix);
138 fs.add(builder.build());
140 final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(
141 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());
147 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
148 .opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes
149 .destination.type.DestinationFlowspecIpv6CaseBuilder()
150 .setDestinationFlowspecIpv6(
151 new DestinationFlowspecIpv6Builder()
159 final MpReachNlriBuilder result = new MpReachNlriBuilder();
160 result.setAfi(Ipv6AddressFamily.class);
161 result.setSafi(FlowspecSubsequentAddressFamily.class);
162 this.fsParser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result, null);
164 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
165 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type
166 .DestinationFlowspecIpv6Case) result.getAdvertizedRoutes().getDestinationType())
167 .getDestinationFlowspecIpv6().getFlowspec();
168 assertEquals(3, flows.size());
169 assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
170 assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
171 assertEquals(headersCase, flows.get(2).getFlowspecType());
173 final ByteBuf buffer = Unpooled.buffer();
174 this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
175 new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(),
177 assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
179 assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ",
180 this.fsParser.stringNlri(flows));
184 public void testParseMpReachNlriConstraint() throws BGPParsingException {
185 final List<Flowspec> fs = new ArrayList<>();
186 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
188 final FlowspecBuilder builder = new FlowspecBuilder();
189 final DestinationIpv6PrefixCase destinationPrefix = new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(
190 new Ipv6Prefix("102:304:500::/40")).build();
191 builder.setFlowspecType(destinationPrefix);
192 fs.add(builder.build());
194 final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(
195 new Ipv6Prefix("102:304:600::/40")).build();
196 builder.setFlowspecType(sourcePrefix);
197 fs.add(builder.build());
199 final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(
200 new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
201 final NextHeaderCase headersCase = new NextHeaderCaseBuilder().setNextHeaders(nextheaders).build();
202 builder.setFlowspecType(headersCase);
203 fs.add(builder.build());
206 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
207 .opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes
208 .destination.type.DestinationFlowspecIpv6CaseBuilder()
209 .setDestinationFlowspecIpv6(
210 new DestinationFlowspecIpv6Builder()
218 final MpReachNlriBuilder result = new MpReachNlriBuilder();
219 result.setAfi(Ipv6AddressFamily.class);
220 result.setSafi(FlowspecSubsequentAddressFamily.class);
221 this.fsParser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
223 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
224 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type
225 .DestinationFlowspecIpv6Case) result.getAdvertizedRoutes().getDestinationType())
226 .getDestinationFlowspecIpv6().getFlowspec();
227 assertEquals(3, flows.size());
228 assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
229 assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
230 assertEquals(headersCase, flows.get(2).getFlowspecType());
232 final ByteBuf buffer = Unpooled.buffer();
233 this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
234 new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(),
236 assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
238 assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ",
239 this.fsParser.stringNlri(flows));
243 public void testParseMpUnreachNlri() throws BGPParsingException {
244 final List<Flowspec> fs = new ArrayList<>();
245 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
247 final FlowspecBuilder builder = new FlowspecBuilder();
249 final FragmentCase fragment = createFragment();
250 builder.setFlowspecType(fragment);
251 fs.add(builder.build());
253 final FlowspecType label = createLabel();
254 builder.setFlowspecType(label);
255 fs.add(builder.build());
257 mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
258 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
259 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
260 .setDestinationFlowspecIpv6(
261 new DestinationFlowspecIpv6Builder()
268 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
269 result.setAfi(Ipv6AddressFamily.class);
270 result.setSafi(FlowspecSubsequentAddressFamily.class);
271 this.fsParser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result, null);
273 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
274 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
275 .DestinationFlowspecIpv6Case) result.getWithdrawnRoutes().getDestinationType())
276 .getDestinationFlowspecIpv6().getFlowspec();
277 assertEquals(2, flows.size());
278 assertEquals(fragment, flows.get(0).getFlowspecType());
279 assertEquals(label, flows.get(1).getFlowspecType());
281 final ByteBuf buffer = Unpooled.buffer();
282 this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
283 new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
285 assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
287 assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to "
288 + "16777222 or equals to 258 ", this.fsParser.stringNlri(flows));
291 private static FragmentCase createFragment() {
292 final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder().setOp(
293 new BitmaskOperand(false, true, true, false)).setValue(new Fragment(false, true, true, true)).build());
294 return new FragmentCaseBuilder().setFragments(fragments).build();
297 private static FlowspecType createLabel() {
298 final List<FlowLabel> labels = new ArrayList<>(2);
299 labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, false, true, false, false))
300 .setValue(16777222L).build());
301 labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, true, true, false, false))
302 .setValue(258L).build());
303 return new FlowLabelCaseBuilder().setFlowLabel(labels).build();
307 public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
308 final List<Flowspec> fs = new ArrayList<>();
309 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
311 final FlowspecBuilder builder = new FlowspecBuilder();
312 final FragmentCase fragment = createFragment();
314 builder.setFlowspecType(fragment);
315 fs.add(builder.build());
317 final FlowspecType label = createLabel();
318 builder.setFlowspecType(label);
319 fs.add(builder.build());
321 mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
322 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
323 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
324 .setDestinationFlowspecIpv6(
325 new DestinationFlowspecIpv6Builder()
333 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
334 result.setAfi(Ipv6AddressFamily.class);
335 result.setSafi(FlowspecSubsequentAddressFamily.class);
336 this.fsParser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
338 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
339 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
340 .DestinationFlowspecIpv6Case) result.getWithdrawnRoutes().getDestinationType())
341 .getDestinationFlowspecIpv6().getFlowspec();
342 assertEquals(2, flows.size());
343 assertEquals(fragment, flows.get(0).getFlowspecType());
344 assertEquals(label, flows.get(1).getFlowspecType());
346 final ByteBuf buffer = Unpooled.buffer();
347 this.fsParser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
348 new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
350 assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
352 assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to "
353 + "16777222 or equals to 258 ", this.fsParser.stringNlri(flows));
357 public void testExtractFlowspecFragments() {
358 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
359 Builders.mapEntryBuilder();
360 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
361 entry.withChild(Builders.unkeyedListBuilder()
362 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
363 .withChild(Builders.unkeyedListEntryBuilder()
364 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
365 .withChild(Builders.choiceBuilder()
366 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
367 .withChild(Builders.unkeyedListBuilder()
368 .withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
369 .withChild(Builders.unkeyedListEntryBuilder()
370 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
371 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
372 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
373 AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE,
374 BitmaskOperandParser.NOT_VALUE)).build())
375 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
376 .withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE,
377 AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE,
378 AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
379 .build()).build()).build()).build());
380 final FlowspecBuilder expectedFS = new FlowspecBuilder();
381 expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder()
382 .setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build()))
384 final List<Flowspec> expectedValue = new ArrayList<>();
385 expectedValue.add(expectedFS.build());
386 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
390 public void testExtractFlowspecNextHeaders() {
391 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
392 Builders.mapEntryBuilder();
393 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
394 entry.withChild(Builders.unkeyedListBuilder()
395 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
396 .withChild(Builders.unkeyedListEntryBuilder()
397 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
398 .withChild(Builders.choiceBuilder()
399 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
400 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(NEXT_HEADER_NID)
401 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
402 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
403 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
404 AbstractOperandParser.AND_BIT_VALUE)).build())
405 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
406 .withValue(Uint8.valueOf(100)).build()).build())
407 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
408 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
409 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
410 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
411 .withValue(Uint8.valueOf(200)).build()).build())
412 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
413 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
414 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
415 AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE))
417 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
418 .withValue(Uint8.valueOf(210)).build()).build())
419 .build()).build()).build()).build());
421 final FlowspecBuilder expectedFS = new FlowspecBuilder();
422 expectedFS.setFlowspecType(new NextHeaderCaseBuilder().setNextHeaders(Lists.newArrayList(
423 new NextHeadersBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false))
425 new NextHeadersBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false))
427 new NextHeadersBuilder().setValue((short) 210).setOp(new NumericOperand(true, true, true, false, false))
429 final List<Flowspec> expectedValue = new ArrayList<>();
430 expectedValue.add(expectedFS.build());
431 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
435 public void testExtractFlowspecFlowLabels() {
436 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
437 Builders.mapEntryBuilder();
438 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
439 entry.withChild(Builders.unkeyedListBuilder()
440 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
441 .withChild(Builders.unkeyedListEntryBuilder()
442 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
443 .withChild(Builders.choiceBuilder()
444 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
445 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FLOW_LABEL_NID)
446 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
447 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
448 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
449 AbstractOperandParser.AND_BIT_VALUE)).build())
450 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
451 .withValue(Uint32.valueOf(100)).build()).build())
452 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
453 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
454 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
455 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
456 .withValue(Uint32.valueOf(200)).build()).build())
457 .build()).build()).build()).build());
459 final FlowspecBuilder expectedFS = new FlowspecBuilder();
460 expectedFS.setFlowspecType(new FlowLabelCaseBuilder().setFlowLabel(Lists.newArrayList(
461 new FlowLabelBuilder().setValue(100L).setOp(new NumericOperand(true, true, false, false, false)).build(),
462 new FlowLabelBuilder().setValue(200L).setOp(new NumericOperand(true, false, false, false, false)).build()))
464 final List<Flowspec> expectedValue = new ArrayList<>();
465 expectedValue.add(expectedFS.build());
466 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
470 public void testExtractFlowspecDestPrefix() {
471 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
472 Builders.mapEntryBuilder();
473 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
474 entry.withChild(Builders.unkeyedListBuilder()
475 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
476 .withChild(Builders.unkeyedListEntryBuilder()
477 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
478 .withChild(Builders.choiceBuilder()
479 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
480 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID)
481 .withValue("102:304:500::/40").build()).build()).build()).build());
482 final FlowspecBuilder expectedFS = new FlowspecBuilder();
483 expectedFS.setFlowspecType(new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(
484 new Ipv6Prefix("102:304:500::/40")).build());
485 final List<Flowspec> expectedValue = new ArrayList<>();
486 expectedValue.add(expectedFS.build());
487 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));
491 public void testExtractFlowspecSourcePrefix() {
492 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
493 Builders.mapEntryBuilder();
494 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
495 entry.withChild(Builders.unkeyedListBuilder()
496 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
497 .withChild(Builders.unkeyedListEntryBuilder()
498 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
499 .withChild(Builders.choiceBuilder()
500 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
501 .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.SOURCE_PREFIX_NID)
502 .withValue("102:304:600::/40").build()).build()).build()).build());
503 final FlowspecBuilder expectedFS = new FlowspecBuilder();
504 expectedFS.setFlowspecType(new SourceIpv6PrefixCaseBuilder().setSourcePrefix(
505 new Ipv6Prefix("102:304:600::/40")).build());
506 final List<Flowspec> expectedValue = new ArrayList<>();
507 expectedValue.add(expectedFS.build());
508 assertEquals(expectedValue, this.fsParser.extractFlowspec(entry.build()));