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