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