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