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