Use new Uint* constants
[bgpcep.git] / bgp / extensions / flowspec / src / test / java / org / opendaylight / protocol / bgp / flowspec / SimpleFlowspecIpv4NlriParserTest.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.mockito.ArgumentMatchers.any;
13 import static org.mockito.Mockito.doReturn;
14
15 import com.google.common.collect.Lists;
16 import com.google.common.collect.Sets;
17 import io.netty.buffer.ByteBuf;
18 import io.netty.buffer.Unpooled;
19 import java.util.ArrayList;
20 import java.util.Collections;
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.Ipv4Prefix;
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.Dscp;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.FlowspecSubsequentAddressFamily;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.Fragment;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.NumericOperand;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.Flowspec;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.FlowspecBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.FlowspecType;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.DestinationPortCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.DscpCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.IcmpCodeCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.IcmpTypeCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PacketLengthCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PacketLengthCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PortCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PortCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.SourcePortCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.TcpFlagsCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.TcpFlagsCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPorts;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPortsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.dscp._case.Dscps;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.dscp._case.DscpsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.fragment._case.Fragments;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.fragment._case.FragmentsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.code._case.Codes;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.code._case.CodesBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.type._case.Types;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.type._case.TypesBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengths;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengthsBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.port._case.Ports;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.port._case.PortsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePorts;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePortsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlags;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlagsBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCaseBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCaseBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCaseBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIps;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIpsBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.ipv4.DestinationFlowspecIpv4Builder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.ipv4.route.FlowspecRoute;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.PathId;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.AttributesBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1Builder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2Builder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlri;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
95 import org.opendaylight.yangtools.yang.common.Uint16;
96 import org.opendaylight.yangtools.yang.common.Uint32;
97 import org.opendaylight.yangtools.yang.common.Uint8;
98 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
99 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
100 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
101 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
102 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
103
104 public class SimpleFlowspecIpv4NlriParserTest {
105
106     private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
107
108     static final PathId PATH_ID = new PathId(Uint32.ONE);
109     @Mock
110     private PeerSpecificParserConstraint constraint;
111     @Mock
112     private MultiPathSupport muliPathSupport;
113
114     private static final byte[] REACHED_NLRI = new byte[] {
115         0x21,   // NLRI length: 33
116         01, 0x20, 0x0a, 00, 01, 00,
117         02, 0x20, 01, 02, 03, 04,
118         03, (byte) 0x81, 06,
119         04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
120         05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
121         06, (byte) 0x91, 0x1f, (byte) 0x90
122     };
123
124     private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
125         0x0, 0x0, 0x0, 0x1,
126         0x21,   // NLRI length: 33
127         01, 0x20, 0x0a, 00, 01, 00,
128         02, 0x20, 01, 02, 03, 04,
129         03, (byte) 0x81, 06,
130         04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
131         05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
132         06, (byte) 0x91, 0x1f, (byte) 0x90
133     };
134
135     private static final byte[] REACHED_NLRI_BATCHED = new byte[] {
136         0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xf5, 0x65,
137         0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xda, (byte) 0xc4,
138         0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xd8, (byte) 0xc3
139     };
140
141     private static final byte[] UNREACHED_NLRI = new byte[] {
142         0x1B,   // NLRI length: 27
143         07, 4, 2, (byte) 0x84, 3,
144         0x08, 4, 04, (byte) 0x80, 05,
145         0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
146         0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
147         0x0b, (byte) 0x82, 0x2a,
148         0x0c, (byte) 0x81, (byte) 0x0e
149     };
150
151     private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
152         0x0, 0x0, 0x0, 0x1,
153         0x1B,   // NLRI length: 27
154         07, 4, 2, (byte) 0x84, 3,
155         0x08, 4, 04, (byte) 0x80, 05,
156         0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
157         0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
158         0x0b, (byte) 0x82, 0x2a,
159         0x0c, (byte) 0x81, (byte) 0x0e
160     };
161
162     private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
163     private final FlowspecActivator fsa = new FlowspecActivator(this.flowspecContext);
164     private final SimpleFlowspecIpv4NlriParser fsParser = new SimpleFlowspecIpv4NlriParser(
165         flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
166             SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
167
168     @Before
169     public void setUp() {
170         MockitoAnnotations.initMocks(this);
171         doReturn(Optional.of(this.muliPathSupport)).when(this.constraint).getPeerConstraint(any());
172         doReturn(true).when(this.muliPathSupport).isTableTypeSupported(any());
173     }
174
175     @Test
176     public void testParseMpReachNlri() throws BGPParsingException {
177         final List<Flowspec> fs = new ArrayList<>();
178         final MpReachNlriBuilder mp = new MpReachNlriBuilder();
179
180         final FlowspecBuilder builder = new FlowspecBuilder();
181         final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(
182             new Ipv4Prefix("10.0.1.0/32")).build();
183         builder.setFlowspecType(destinationPrefix);
184         fs.add(builder.build());
185         final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder()
186                 .setSourcePrefix(new Ipv4Prefix("1.2.3.4/32")).build();
187         builder.setFlowspecType(sourcePrefix);
188         fs.add(builder.build());
189
190         final FlowspecType prots = createProts();
191         builder.setFlowspecType(prots);
192         fs.add(builder.build());
193
194         final PortCase ps = createPorts();
195         builder.setFlowspecType(ps);
196         fs.add(builder.build());
197
198         final FlowspecType dps = createDps();
199         builder.setFlowspecType(dps);
200         fs.add(builder.build());
201
202         final FlowspecType sps = createSps();
203         builder.setFlowspecType(sps);
204         fs.add(builder.build());
205
206         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
207             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329
208                 .update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
209             .setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder().setFlowspec(fs).build())
210             .build()).build());
211
212         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
213             flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
214                 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
215
216         final MpReachNlriBuilder result = new MpReachNlriBuilder();
217         result.setAfi(Ipv4AddressFamily.class);
218         result.setSafi(FlowspecSubsequentAddressFamily.class);
219         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result, null);
220
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.DestinationFlowspecCase)
223                 result.getAdvertizedRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
224         testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
225
226         final ByteBuf buffer = Unpooled.buffer();
227         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder()
228             .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(), buffer);
229         assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
230
231         assertEquals("all packets to 10.0.1.0/32 AND from 1.2.3.4/32 AND where IP protocol equals to 6 AND where port "
232                 + "is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where "
233                 + "destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ",
234                 this.fsParser.stringNlri(flows));
235     }
236
237     private static void testFlows(final List<Flowspec> flows, final DestinationPrefixCase destinationPrefix,
238             final SourcePrefixCase sourcePrefix, final FlowspecType prots, final PortCase ps, final FlowspecType dps,
239             final FlowspecType sps) {
240         assertEquals(6, flows.size());
241         assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
242         assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
243         assertEquals(prots, flows.get(2).getFlowspecType());
244         assertEquals(ps, flows.get(3).getFlowspecType());
245         assertEquals(dps, flows.get(4).getFlowspecType());
246         assertEquals(sps, flows.get(5).getFlowspecType());
247     }
248
249     private static FlowspecType createSps() {
250         final List<SourcePorts> sports = Lists.newArrayList(new SourcePortsBuilder().setOp(
251             new NumericOperand(false, true, true, false, false)).setValue(Uint16.valueOf(8080)).build());
252         return new SourcePortCaseBuilder().setSourcePorts(sports).build();
253     }
254
255     private static FlowspecType createProts() {
256         final List<ProtocolIps> protocols = Lists.newArrayList(new ProtocolIpsBuilder().setOp(
257             new NumericOperand(false, true, true, false, false)).setValue(Uint8.valueOf(6)).build());
258         return new ProtocolIpCaseBuilder().setProtocolIps(protocols).build();
259     }
260
261     private static FlowspecType createDps() {
262         final List<DestinationPorts> destports = Lists.newArrayList(new DestinationPortsBuilder().setOp(
263             new NumericOperand(false, false, false, true, false)).setValue(Uint16.valueOf(4089)).build(),
264             new DestinationPortsBuilder().setOp(new NumericOperand(false, true, true, false, false))
265                 .setValue(Uint16.valueOf(179)).build());
266         return new DestinationPortCaseBuilder().setDestinationPorts(destports).build();
267     }
268
269     @Test
270     public void testParseMpReachNlriConstraint() throws BGPParsingException {
271         final List<Flowspec> fs = new ArrayList<>();
272         final MpReachNlriBuilder mp = new MpReachNlriBuilder();
273
274         final FlowspecBuilder builder = new FlowspecBuilder();
275         final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(
276             new Ipv4Prefix("10.0.1.0/32")).build();
277         builder.setFlowspecType(destinationPrefix);
278         fs.add(builder.build());
279         final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder().setSourcePrefix(
280             new Ipv4Prefix("1.2.3.4/32")).build();
281         builder.setFlowspecType(sourcePrefix);
282         fs.add(builder.build());
283
284         final FlowspecType prots = createProts();
285         builder.setFlowspecType(prots);
286         fs.add(builder.build());
287
288         final PortCase ps = createPorts();
289         builder.setFlowspecType(ps);
290         fs.add(builder.build());
291
292         final FlowspecType dps = createDps();
293         builder.setFlowspecType(dps);
294         fs.add(builder.build());
295
296         final FlowspecType sps = createSps();
297         builder.setFlowspecType(sps);
298         fs.add(builder.build());
299
300         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
301             .opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes
302             .destination.type.DestinationFlowspecCaseBuilder()
303                 .setDestinationFlowspecIpv4(
304                     new DestinationFlowspecIpv4Builder()
305                         .setPathId(PATH_ID)
306                         .setFlowspec(fs)
307                         .build()
308                 ).build()
309             ).build()
310         );
311
312         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
313             flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
314                 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
315
316         final MpReachNlriBuilder result = new MpReachNlriBuilder();
317         result.setAfi(Ipv4AddressFamily.class);
318         result.setSafi(FlowspecSubsequentAddressFamily.class);
319         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
320
321         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
322                 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase)
323                 result.getAdvertizedRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
324         testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
325
326         final ByteBuf buffer = Unpooled.buffer();
327         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
328             new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(),
329             buffer);
330         assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
331
332         assertEquals("all packets to 10.0.1.0/32 AND from 1.2.3.4/32 AND where IP protocol equals to 6 AND where port "
333                 + "is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where "
334                 + "destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ",
335                 this.fsParser.stringNlri(flows));
336     }
337
338     private static PortCase createPorts() {
339         final List<Ports> ports = Lists.newArrayList(
340             new PortsBuilder().setOp(new NumericOperand(false, false, true, true, false)).setValue(Uint16.valueOf(137))
341                 .build(),
342             new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(Uint16.valueOf(139))
343                 .build(),
344             new PortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(Uint16.valueOf(8080))
345                 .build());
346
347         return new PortCaseBuilder().setPorts(ports).build();
348     }
349
350     @Test
351     public void testParseMpUnreachNlri() throws BGPParsingException {
352         final List<Flowspec> fs = new ArrayList<>();
353         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
354
355         final FlowspecBuilder builder = new FlowspecBuilder();
356
357         final FlowspecType icmpType = createIcmpType();
358         builder.setFlowspecType(icmpType);
359         fs.add(builder.build());
360
361         final FlowspecType icmpCode = createIcmpCode();
362         builder.setFlowspecType(icmpCode);
363         fs.add(builder.build());
364
365         final TcpFlagsCase tcp = createTcp();
366         builder.setFlowspecType(tcp);
367         fs.add(builder.build());
368
369         final PacketLengthCase packet = createPackets();
370         builder.setFlowspecType(packet);
371         fs.add(builder.build());
372
373         final FlowspecType dscp = createDscp();
374         builder.setFlowspecType(dscp);
375         fs.add(builder.build());
376
377         final FlowspecType fragment = createFragment();
378         builder.setFlowspecType(fragment);
379         fs.add(builder.build());
380
381         mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
382             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
383                 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
384                 .setDestinationFlowspecIpv4(
385                     new DestinationFlowspecIpv4Builder()
386                         .setFlowspec(fs)
387                         .build()
388                 ).build()
389             ).build()
390         );
391
392         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
393             this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
394                 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
395
396         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
397         result.setAfi(Ipv4AddressFamily.class);
398         result.setSafi(FlowspecSubsequentAddressFamily.class);
399         parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result, null);
400
401         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
402                 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase)
403                 result.getWithdrawnRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
404         checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
405
406         final ByteBuf buffer = Unpooled.buffer();
407         parser.serializeNlri(new Object[] {flows}, null, buffer);
408         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
409
410         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
411             new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
412         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
413
414         assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 "
415                 + "or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 "
416                 + "AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ",
417                 this.fsParser.stringNlri(flows));
418
419     }
420
421     private static FlowspecType createFragment() {
422         final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder()
423             .setOp(new BitmaskOperand(false, true, true, false))
424             .setValue(new Fragment(false, true, true, true)).build());
425         return new FragmentCaseBuilder().setFragments(fragments).build();
426     }
427
428     private static FlowspecType createDscp() {
429         final List<Dscps> dscps = Lists.newArrayList(new DscpsBuilder()
430             .setOp(new NumericOperand(false, true, false, true, false))
431             .setValue(new Dscp(Uint8.valueOf(42))).build());
432         return new DscpCaseBuilder().setDscps(dscps).build();
433     }
434
435     private static PacketLengthCase createPackets() {
436         final List<PacketLengths> packets = Lists.newArrayList(new PacketLengthsBuilder()
437             .setOp(new NumericOperand(false, true, false, false, true))
438             .setValue(Uint16.valueOf(57005)).build());
439         return new PacketLengthCaseBuilder().setPacketLengths(packets).build();
440     }
441
442     private static TcpFlagsCase createTcp() {
443         final List<TcpFlags> flags = Lists.newArrayList(new TcpFlagsBuilder()
444             .setOp(new BitmaskOperand(false, false, false, true)).setValue(Uint16.valueOf(1025))
445             .build(), new TcpFlagsBuilder()
446             .setOp(new BitmaskOperand(false, true, true, false))
447             .setValue(Uint16.valueOf(22193)).build());
448         return new TcpFlagsCaseBuilder().setTcpFlags(flags).build();
449     }
450
451     private static FlowspecType createIcmpCode() {
452         final List<Codes> codes = Lists.newArrayList(new CodesBuilder()
453             .setOp(new NumericOperand(false, false, false, false, true))
454             .setValue(Uint8.valueOf(4))
455             .build(), new CodesBuilder()
456             .setOp(new NumericOperand(false, true, false, false, false))
457             .setValue(Uint8.valueOf(5)).build());
458         return new IcmpCodeCaseBuilder().setCodes(codes).build();
459     }
460
461     private static FlowspecType createIcmpType() {
462         final List<Types> types = Lists.newArrayList(
463             new TypesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue(Uint8.TWO)
464                 .build(),
465             new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue(Uint8.valueOf(3))
466                 .build());
467         return new IcmpTypeCaseBuilder().setTypes(types).build();
468     }
469
470     private static void checkUnreachFlows(final List<Flowspec> flows, final FlowspecType icmpType,
471             final FlowspecType icmpCode, final TcpFlagsCase tcp, final PacketLengthCase packet,
472             final FlowspecType dscp, final FlowspecType fragment) {
473         assertEquals(6, flows.size());
474         assertEquals(icmpType, flows.get(0).getFlowspecType());
475         assertEquals(icmpCode, flows.get(1).getFlowspecType());
476         assertEquals(tcp, flows.get(2).getFlowspecType());
477         assertEquals(packet, flows.get(3).getFlowspecType());
478         assertEquals(dscp, flows.get(4).getFlowspecType());
479         assertEquals(fragment, flows.get(5).getFlowspecType());
480     }
481
482     @Test
483     public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
484         final List<Flowspec> fs = new ArrayList<>();
485         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
486
487         final FlowspecBuilder builder = new FlowspecBuilder();
488
489         final FlowspecType icmpType = createIcmpType();
490         builder.setFlowspecType(icmpType);
491         fs.add(builder.build());
492
493         final FlowspecType icmpCode = createIcmpCode();
494         builder.setFlowspecType(icmpCode);
495         fs.add(builder.build());
496
497         final TcpFlagsCase tcp = createTcp();
498         builder.setFlowspecType(tcp);
499         fs.add(builder.build());
500
501         final PacketLengthCase packet = createPackets();
502         builder.setFlowspecType(packet);
503         fs.add(builder.build());
504
505         final FlowspecType dscp = createDscp();
506         builder.setFlowspecType(dscp);
507         fs.add(builder.build());
508
509         final FlowspecType fragment = createFragment();
510         builder.setFlowspecType(fragment);
511         fs.add(builder.build());
512
513         mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
514             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
515                 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
516                 .setDestinationFlowspecIpv4(
517                     new DestinationFlowspecIpv4Builder()
518                         .setPathId(PATH_ID)
519                         .setFlowspec(fs)
520                         .build()
521                 ).build()
522             ).build()
523         );
524
525         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
526             this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
527                 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
528
529         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
530         result.setAfi(Ipv4AddressFamily.class);
531         result.setSafi(FlowspecSubsequentAddressFamily.class);
532         parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
533
534         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
535                 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase)
536                 result.getWithdrawnRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
537         checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
538
539
540         final ByteBuf buffer = Unpooled.buffer();
541         parser.serializeNlri(new Object[] {flows}, PATH_ID, buffer);
542         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
543
544         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
545             new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
546         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
547
548         assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 "
549                 + "or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 "
550                 + "AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ",
551                 this.fsParser.stringNlri(flows));
552
553     }
554
555     @Test
556     public void testExtractFlowspecDestPrefix() {
557         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
558                 Builders.mapEntryBuilder();
559         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
560         entry.withChild(Builders.unkeyedListBuilder()
561             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
562             .withChild(Builders.unkeyedListEntryBuilder()
563                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
564                 .withChild(Builders.choiceBuilder()
565                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
566                     .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID)
567                         .withValue("127.0.0.5/32").build()).build()).build()).build());
568
569         final FlowspecBuilder expectedFS = new FlowspecBuilder();
570         expectedFS.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(
571             new Ipv4Prefix("127.0.0.5/32")).build());
572         final List<Flowspec> expected = new ArrayList<>();
573         expected.add(expectedFS.build());
574         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
575     }
576
577     @Test
578     public void testExtractFlowspecSourcePrefix() {
579         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
580                 Builders.mapEntryBuilder();
581         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
582         entry.withChild(Builders.unkeyedListBuilder()
583             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
584             .withChild(Builders.unkeyedListEntryBuilder()
585                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
586                 .withChild(Builders.choiceBuilder()
587                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
588                     .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID)
589                         .withValue("127.0.0.6/32").build()).build()).build()).build());
590
591         final FlowspecBuilder expectedFS = new FlowspecBuilder();
592         expectedFS.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32"))
593             .build());
594         final List<Flowspec> expected = new ArrayList<>();
595         expected.add(expectedFS.build());
596         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
597     }
598
599     @Test
600     public void testExtractFlowspecProtocolIps() {
601         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
602                 Builders.mapEntryBuilder();
603         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
604         entry.withChild(Builders.unkeyedListBuilder()
605             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
606             .withChild(Builders.unkeyedListEntryBuilder()
607                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
608                 .withChild(Builders.choiceBuilder()
609                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
610                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
611                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
612                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
613                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
614                                     AbstractOperandParser.AND_BIT_VALUE)).build())
615                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
616                                 .withValue(Uint8.valueOf(100)).build()).build())
617                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
618                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
619                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
620                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
621                                 .withValue(Uint8.valueOf(200)).build()).build())
622                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
623                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
624                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
625                                     AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE))
626                                 .build())
627                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
628                                 .withValue(Uint8.valueOf(240)).build()).build())
629                         .build()).build()).build()).build());
630
631         final FlowspecBuilder expectedFS = new FlowspecBuilder();
632         expectedFS.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(
633             Lists.newArrayList(
634                 new ProtocolIpsBuilder().setValue(Uint8.valueOf(100)).setOp(
635                     new NumericOperand(true, true, false, false, false)).build(),
636                 new ProtocolIpsBuilder().setValue(Uint8.valueOf(200)).setOp(
637                     new NumericOperand(true, false, false, false, false)).build(),
638                 new ProtocolIpsBuilder().setValue(Uint8.valueOf(240)).setOp(
639                     new NumericOperand(true, true, true, false, false)).build())).build());
640         final List<Flowspec> expected = new ArrayList<>();
641         expected.add(expectedFS.build());
642         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
643     }
644
645     @Test
646     public void testExtractFlowspecPorts() {
647         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
648                 Builders.mapEntryBuilder();
649         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
650         entry.withChild(Builders.unkeyedListBuilder()
651             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
652             .withChild(Builders.unkeyedListEntryBuilder()
653                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
654                 .withChild(Builders.choiceBuilder()
655                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
656                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
657                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
658                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
659                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
660                                     AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE))
661                                 .build())
662                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
663                                 .withValue(Uint16.valueOf(100)).build()).build())
664                         .build()).build()).build()).build());
665
666         final FlowspecBuilder expectedFS = new FlowspecBuilder()
667                 .setFlowspecType(new PortCaseBuilder()
668                     .setPorts(Lists.newArrayList(new PortsBuilder()
669                         .setValue(Uint16.valueOf(100))
670                         .setOp(new NumericOperand(true, true, false, false, true))
671                         .build()))
672                     .build());
673         final List<Flowspec> expected = new ArrayList<>();
674         expected.add(expectedFS.build());
675         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
676     }
677
678     @Test
679     public void testExtractFlowspecDestinationPorts() {
680         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
681                 Builders.mapEntryBuilder();
682         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
683         entry.withChild(Builders.unkeyedListBuilder()
684             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
685             .withChild(Builders.unkeyedListEntryBuilder()
686                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
687                 .withChild(Builders.choiceBuilder()
688                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
689                     .withChild(Builders.unkeyedListBuilder()
690                         .withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PORT_NID)
691                         .withChild(Builders.unkeyedListEntryBuilder()
692                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
693                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
694                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
695                                     AbstractNumericOperandParser.EQUALS_VALUE)).build())
696                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
697                                 .withValue(Uint16.valueOf(1024)).build()).build())
698                         .build()).build()).build()).build());
699         final FlowspecBuilder expectedFS = new FlowspecBuilder();
700         expectedFS.setFlowspecType(new DestinationPortCaseBuilder()
701             .setDestinationPorts(Lists.newArrayList(new DestinationPortsBuilder()
702                 .setValue(Uint16.valueOf(1024))
703                 .setOp(new NumericOperand(false, true, true, false, false))
704                 .build()))
705             .build());
706         final List<Flowspec> expected = new ArrayList<>();
707         expected.add(expectedFS.build());
708         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
709     }
710
711     @Test
712     public void testExtractFlowspecSourcePorts() {
713         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
714                 Builders.mapEntryBuilder();
715         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
716         entry.withChild(Builders.unkeyedListBuilder()
717             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
718             .withChild(Builders.unkeyedListEntryBuilder()
719                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
720                 .withChild(Builders.choiceBuilder()
721                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
722                     .withChild(Builders.unkeyedListBuilder()
723                         .withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PORT_NID)
724                         .withChild(Builders.unkeyedListEntryBuilder()
725                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
726                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
727                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
728                                     AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
729                                     AbstractNumericOperandParser.GREATER_THAN_VALUE,
730                                     AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
731                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
732                                 .withValue(Uint16.valueOf(8080)).build()).build())
733                         .build()).build()).build()).build());
734         final FlowspecBuilder expectedFS = new FlowspecBuilder();
735         expectedFS.setFlowspecType(new SourcePortCaseBuilder()
736             .setSourcePorts(Lists.newArrayList(new SourcePortsBuilder()
737                 .setValue(Uint16.valueOf(8080))
738                 .setOp(new NumericOperand(true, true, true, true, true))
739                 .build()))
740             .build());
741         final List<Flowspec> expected = new ArrayList<>();
742         expected.add(expectedFS.build());
743         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
744     }
745
746     @Test
747     public void testExtractFlowspecSourceTypes() {
748         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
749                 Builders.mapEntryBuilder();
750         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
751         entry.withChild(Builders.unkeyedListBuilder()
752             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
753             .withChild(Builders.unkeyedListEntryBuilder()
754                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
755                 .withChild(Builders.choiceBuilder()
756                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
757                     .withChild(Builders.unkeyedListBuilder()
758                         .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_TYPE_NID)
759                         .withChild(Builders.unkeyedListEntryBuilder()
760                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
761                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
762                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
763                                     AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
764                                     AbstractNumericOperandParser.GREATER_THAN_VALUE,
765                                     AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
766                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
767                                 .withValue(Uint8.valueOf(22)).build()).build())
768                         .build()).build()).build()).build());
769         final FlowspecBuilder expectedFS = new FlowspecBuilder();
770         expectedFS.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(Lists.newArrayList(new TypesBuilder()
771             .setValue(Uint8.valueOf(22)).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
772         final List<Flowspec> expected = new ArrayList<>();
773         expected.add(expectedFS.build());
774         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
775     }
776
777     @Test
778     public void testExtractFlowspecSourceCodes() {
779         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
780                 Builders.mapEntryBuilder();
781         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
782         entry.withChild(Builders.unkeyedListBuilder()
783             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
784             .withChild(Builders.unkeyedListEntryBuilder()
785                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
786                 .withChild(Builders.choiceBuilder()
787                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
788                     .withChild(Builders.unkeyedListBuilder()
789                         .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_CODE_NID)
790                         .withChild(Builders.unkeyedListEntryBuilder()
791                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
792                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
793                                 .withValue(Collections.emptySet()).build())
794                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
795                                 .withValue(Uint8.valueOf(23)).build()).build())
796                         .build()).build()).build()).build());
797         final FlowspecBuilder expectedFS = new FlowspecBuilder();
798         expectedFS.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(Lists.newArrayList(new CodesBuilder()
799             .setValue(Uint8.valueOf(23)).setOp(new NumericOperand(false, false, false, false, false)).build()))
800             .build());
801         final List<Flowspec> expected = new ArrayList<>();
802         expected.add(expectedFS.build());
803         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
804     }
805
806     @Test
807     public void testExtractFlowspecSourceTcpFlags() {
808         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
809                 Builders.mapEntryBuilder();
810         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
811         entry.withChild(Builders.unkeyedListBuilder()
812             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
813             .withChild(Builders.unkeyedListEntryBuilder()
814                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
815                 .withChild(Builders.choiceBuilder()
816                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
817                     .withChild(Builders.unkeyedListBuilder()
818                         .withNodeIdentifier(AbstractFlowspecNlriParser.TCP_FLAGS_NID)
819                         .withChild(Builders.unkeyedListEntryBuilder()
820                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
821                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
822                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
823                                     AbstractOperandParser.END_OF_LIST_VALUE)).build())
824                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
825                                 .withValue(Uint16.valueOf(99)).build()).build())
826                         .build()).build()).build()).build());
827         final FlowspecBuilder expectedFS = new FlowspecBuilder();
828         expectedFS.setFlowspecType(new TcpFlagsCaseBuilder()
829             .setTcpFlags(Lists.newArrayList(new TcpFlagsBuilder()
830                 .setValue(Uint16.valueOf(99))
831                 .setOp(new BitmaskOperand(true, true, false, false))
832                 .build()))
833             .build());
834         final List<Flowspec> expected = new ArrayList<>();
835         expected.add(expectedFS.build());
836         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
837     }
838
839     @Test
840     public void testExtractFlowspecPacketLengths() {
841         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
842                 Builders.mapEntryBuilder();
843         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
844         entry.withChild(Builders.unkeyedListBuilder()
845             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
846             .withChild(Builders.unkeyedListEntryBuilder()
847                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
848                 .withChild(Builders.choiceBuilder()
849                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
850                     .withChild(Builders.unkeyedListBuilder()
851                         .withNodeIdentifier(AbstractFlowspecNlriParser.PACKET_LENGTHS_NID)
852                         .withChild(Builders.unkeyedListEntryBuilder()
853                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
854                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
855                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
856                                     AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
857                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
858                                 .withValue(Uint16.valueOf(101)).build()).build())
859                         .build()).build()).build()).build());
860         final FlowspecBuilder expectedFS = new FlowspecBuilder();
861         expectedFS.setFlowspecType(new PacketLengthCaseBuilder()
862             .setPacketLengths(Lists.newArrayList(new PacketLengthsBuilder()
863                 .setValue(Uint16.valueOf(101))
864                 .setOp(new NumericOperand(true, false, false, true, false))
865                 .build()))
866             .build());
867         final List<Flowspec> expected = new ArrayList<>();
868         expected.add(expectedFS.build());
869         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
870     }
871
872     @Test
873     public void testExtractFlowspecDscps() {
874         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
875                 Builders.mapEntryBuilder();
876         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
877         entry.withChild(Builders.unkeyedListBuilder()
878             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
879             .withChild(Builders.unkeyedListEntryBuilder()
880                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
881                 .withChild(Builders.choiceBuilder()
882                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
883                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
884                         .withChild(Builders.unkeyedListEntryBuilder()
885                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
886                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
887                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
888                                     AbstractOperandParser.END_OF_LIST_VALUE,
889                                     AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
890                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
891                                 .withValue(Uint8.valueOf(15)).build()).build())
892                         .build()).build()).build()).build());
893         final FlowspecBuilder expectedFS = new FlowspecBuilder();
894         expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(Lists.newArrayList(new DscpsBuilder()
895             .setValue(new Dscp(Uint8.valueOf(15))).setOp(new NumericOperand(true, true, false, true, false)).build()))
896             .build());
897         final List<Flowspec> expected = new ArrayList<>();
898         expected.add(expectedFS.build());
899         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
900     }
901
902     @Test
903     public void testExtractFlowspecFragments() {
904         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
905                 Builders.mapEntryBuilder();
906         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
907         entry.withChild(Builders.unkeyedListBuilder()
908             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
909             .withChild(Builders.unkeyedListEntryBuilder()
910                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
911                 .withChild(Builders.choiceBuilder()
912                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
913                     .withChild(Builders.unkeyedListBuilder()
914                         .withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
915                         .withChild(Builders.unkeyedListEntryBuilder()
916                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
917                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
918                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
919                                     AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE,
920                                     BitmaskOperandParser.NOT_VALUE)).build())
921                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
922                                 .withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE,
923                                     AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE,
924                                     AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
925                         .build()).build()).build()).build());
926         final FlowspecBuilder expectedFS = new FlowspecBuilder();
927         expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder()
928             .setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build()))
929             .build());
930         final List<Flowspec> expected = new ArrayList<>();
931         expected.add(expectedFS.build());
932         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
933     }
934
935     @Test
936     public void testBatchedFlowspecNlri() throws Exception {
937         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
938             flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
939                 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
940
941         final MpReachNlriBuilder result = new MpReachNlriBuilder();
942         result.setAfi(Ipv4AddressFamily.class);
943         result.setSafi(FlowspecSubsequentAddressFamily.class);
944
945         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_BATCHED), result, null);
946         final MpReachNlri nlri = result.build();
947
948         final List<Flowspec> flowspecList = ((DestinationFlowspecCase) nlri.getAdvertizedRoutes().getDestinationType())
949                 .getDestinationFlowspecIpv4().getFlowspec();
950         assertEquals(3, flowspecList.size());
951         assertEquals("216.58.245.101/32", ((DestinationPrefixCase) flowspecList.get(0).getFlowspecType())
952             .getDestinationPrefix().getValue());
953         assertEquals("216.58.218.196/32", ((DestinationPrefixCase) flowspecList.get(1).getFlowspecType())
954             .getDestinationPrefix().getValue());
955         assertEquals("216.58.216.195/32", ((DestinationPrefixCase) flowspecList.get(2).getFlowspecType())
956             .getDestinationPrefix().getValue());
957     }
958 }
959