c3b64688839acb656a885417115b755cd73cdebc
[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.junit.runner.RunWith;
27 import org.mockito.Mock;
28 import org.mockito.junit.MockitoJUnitRunner;
29 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractNumericOperandParser;
30 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractOperandParser;
31 import org.opendaylight.protocol.bgp.flowspec.handlers.BitmaskOperandParser;
32 import org.opendaylight.protocol.bgp.flowspec.l3vpn.AbstractFlowspecL3vpnNlriParser;
33 import org.opendaylight.protocol.bgp.flowspec.l3vpn.ipv4.FlowspecL3vpnIpv4NlriParser;
34 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
35 import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupport;
36 import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
37 import org.opendaylight.protocol.util.ByteArray;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.BitmaskOperand;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.Dscp;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.FlowspecL3vpnSubsequentAddressFamily;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.Fragment;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.NumericOperand;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.Flowspec;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.FlowspecBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.FlowspecType;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.DestinationPortCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.DscpCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.IcmpCodeCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.IcmpTypeCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.PacketLengthCase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.PacketLengthCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.PortCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.PortCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.SourcePortCaseBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.TcpFlagsCase;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.TcpFlagsCaseBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPorts;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPortsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.dscp._case.Dscps;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.dscp._case.DscpsBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.fragment._case.Fragments;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.fragment._case.FragmentsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.icmp.code._case.Codes;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.icmp.code._case.CodesBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.icmp.type._case.Types;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.icmp.type._case.TypesBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengths;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengthsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.port._case.Ports;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.port._case.PortsBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePorts;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePortsBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlags;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlagsBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCase;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCaseBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCaseBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCase;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCaseBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIps;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIpsBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.ipv4.route.FlowspecRoute;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.l3vpn.destination.ipv4.DestinationFlowspecL3vpnIpv4;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.l3vpn.destination.ipv4.DestinationFlowspecL3vpnIpv4Builder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
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.Attributes2Builder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
98 import org.opendaylight.yangtools.yang.common.QName;
99 import org.opendaylight.yangtools.yang.common.Uint16;
100 import org.opendaylight.yangtools.yang.common.Uint32;
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 @RunWith(MockitoJUnitRunner.StrictStubs.class)
109 public class FlowspecL3vpnIpv4NlriParserTest {
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(Uint32.ONE);
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         doReturn(Optional.of(this.muliPathSupport)).when(this.constraint).getPeerConstraint(any());
178         doReturn(true).when(this.muliPathSupport).isTableTypeSupported(any());
179     }
180
181     @Test
182     public void testParseMpReachNlri() throws BGPParsingException {
183         final List<Flowspec> fs = new ArrayList<>();
184         final MpReachNlriBuilder mp = new MpReachNlriBuilder();
185
186         final FlowspecBuilder builder = new FlowspecBuilder();
187         final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(
188             new Ipv4Prefix("10.0.1.0/32")).build();
189         builder.setFlowspecType(destinationPrefix);
190         fs.add(builder.build());
191         final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder().setSourcePrefix(
192             new Ipv4Prefix("1.2.3.4/32")).build();
193         builder.setFlowspecType(sourcePrefix);
194         fs.add(builder.build());
195
196         final FlowspecType prots = createProts();
197         builder.setFlowspecType(prots);
198         fs.add(builder.build());
199
200         final PortCase ps = createPorts();
201         builder.setFlowspecType(ps);
202         fs.add(builder.build());
203
204         final FlowspecType dps = createDps();
205         builder.setFlowspecType(dps);
206         fs.add(builder.build());
207
208         final FlowspecType sps = createSps();
209         builder.setFlowspecType(sps);
210         fs.add(builder.build());
211
212         final FlowspecL3vpnIpv4NlriParser parser = new FlowspecL3vpnIpv4NlriParser(
213             this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
214                 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
215
216         final MpReachNlriBuilder result = new MpReachNlriBuilder();
217         result.setAfi(Ipv4AddressFamily.class);
218         result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
219         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result, null);
220
221         final DestinationFlowspecL3vpnIpv4 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns
222                 .yang.bgp.flowspec.rev200120.update.attributes.mp.reach.nlri.advertized.routes.destination.type
223                 .DestinationFlowspecL3vpnIpv4Case) result.getAdvertizedRoutes().getDestinationType())
224                 .getDestinationFlowspecL3vpnIpv4();
225         final List<Flowspec> flows = flowspecDst.getFlowspec();
226         final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
227
228         testFlows(flows, destinationPrefix, sourcePrefix, prots, rd, ps, dps, sps);
229
230         mp.setAdvertizedRoutes(
231             new AdvertizedRoutesBuilder().setDestinationType(
232                 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
233                 .attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
234                     .setDestinationFlowspecL3vpnIpv4(
235                         new DestinationFlowspecL3vpnIpv4Builder()
236                             .setRouteDistinguisher(rd)
237                             .setFlowspec(fs)
238                             .build()
239                     ).build()
240             ).build()
241         );
242
243         final ByteBuf buffer = Unpooled.buffer();
244         parser.serializeAttribute(new AttributesBuilder()
245             .addAugmentation(new Attributes1Builder()
246                 .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build())
247                 .build())
248             .build(), 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.rev200120.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.rev200120.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()
363             .addAugmentation(new Attributes1Builder()
364                 .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build())
365                 .build())
366             .build(), buffer);
367         assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
368
369         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 "
370                 + "is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where "
371                 + "destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ",
372                 this.fsParser.stringNlri(flows));
373     }
374
375     private static PortCase createPorts() {
376         final List<Ports> ports = Lists.newArrayList(
377             new PortsBuilder().setOp(new NumericOperand(false, false, true, true, false)).setValue(Uint16.valueOf(137))
378                 .build(),
379             new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(Uint16.valueOf(139))
380                 .build(),
381             new PortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(Uint16.valueOf(8080))
382                 .build());
383
384         return new PortCaseBuilder().setPorts(ports).build();
385     }
386
387     @Test
388     public void testParseMpUnreachNlri() throws BGPParsingException {
389         final List<Flowspec> fs = new ArrayList<>();
390         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
391
392         final FlowspecBuilder builder = new FlowspecBuilder();
393
394         final FlowspecType icmpType = createIcmpType();
395         builder.setFlowspecType(icmpType);
396         fs.add(builder.build());
397
398         final FlowspecType icmpCode = createIcmpCode();
399         builder.setFlowspecType(icmpCode);
400         fs.add(builder.build());
401
402         final TcpFlagsCase tcp = createTcp();
403         builder.setFlowspecType(tcp);
404         fs.add(builder.build());
405
406         final PacketLengthCase packet = createPackets();
407         builder.setFlowspecType(packet);
408         fs.add(builder.build());
409
410         final FlowspecType dscp = createDscp();
411         builder.setFlowspecType(dscp);
412         fs.add(builder.build());
413
414         final FlowspecType fragment = createFragment();
415         builder.setFlowspecType(fragment);
416         fs.add(builder.build());
417
418         final FlowspecL3vpnIpv4NlriParser parser = new FlowspecL3vpnIpv4NlriParser(
419             this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
420                 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
421
422         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
423         result.setAfi(Ipv4AddressFamily.class);
424         result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
425         parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result, null);
426
427         DestinationFlowspecL3vpnIpv4 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
428                 .bgp.flowspec.rev200120.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
429                 .DestinationFlowspecL3vpnIpv4Case) result.getWithdrawnRoutes().getDestinationType())
430                 .getDestinationFlowspecL3vpnIpv4();
431         final List<Flowspec> flows = flowspecDst.getFlowspec();
432         checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
433
434         final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
435
436         mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
437             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
438             .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
439                 .setDestinationFlowspecL3vpnIpv4(
440                     new DestinationFlowspecL3vpnIpv4Builder()
441                         .setRouteDistinguisher(rd)
442                         .setFlowspec(fs)
443                         .build()
444                 ).build()
445             ).build()
446         );
447
448         final ByteBuf buffer = Unpooled.buffer();
449         parser.serializeNlri(new Object[] {rd, flows}, null, buffer);
450         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
451
452         parser.serializeAttribute(new AttributesBuilder()
453             .addAugmentation(new Attributes2Builder().setMpUnreachNlri(mp.build()).build())
454             .build(), buffer);
455         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
456
457         assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 "
458                 + "or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 "
459                 + "AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ",
460                 this.fsParser.stringNlri(flows));
461
462     }
463
464     private static FlowspecType createFragment() {
465         final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder().setOp(
466             new BitmaskOperand(false, true, true, false)).setValue(new Fragment(false, true, true, true)).build());
467         return new FragmentCaseBuilder().setFragments(fragments).build();
468     }
469
470     private static FlowspecType createDscp() {
471         final List<Dscps> dscps = Lists.newArrayList(new DscpsBuilder().setOp(
472             new NumericOperand(false, true, false, true, false)).setValue(new Dscp(Uint8.valueOf(42))).build());
473         return new DscpCaseBuilder().setDscps(dscps).build();
474     }
475
476     private static PacketLengthCase createPackets() {
477         final List<PacketLengths> packets = Lists.newArrayList(new PacketLengthsBuilder().setOp(
478             new NumericOperand(false, true, false, false, true)).setValue(Uint16.valueOf(57005)).build());
479         return new PacketLengthCaseBuilder().setPacketLengths(packets).build();
480     }
481
482     private static TcpFlagsCase createTcp() {
483         final List<TcpFlags> flags = Lists.newArrayList(
484             new TcpFlagsBuilder().setOp(new BitmaskOperand(false, false, false, true)).setValue(Uint16.valueOf(1025))
485                 .build(),
486             new TcpFlagsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(Uint16.valueOf(22193))
487                 .build());
488         return new TcpFlagsCaseBuilder().setTcpFlags(flags).build();
489     }
490
491     private static FlowspecType createIcmpCode() {
492         final List<Codes> codes = Lists.newArrayList(
493             new CodesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue(Uint8.valueOf(4))
494                 .build(),
495             new CodesBuilder().setOp(new NumericOperand(false, true, false, false, false)).setValue(Uint8.valueOf(5))
496                 .build());
497         return new IcmpCodeCaseBuilder().setCodes(codes).build();
498     }
499
500     private static FlowspecType createIcmpType() {
501         final List<Types> types = Lists.newArrayList(
502             new TypesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue(Uint8.TWO)
503                 .build(),
504             new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue(Uint8.valueOf(3))
505                 .build());
506         return new IcmpTypeCaseBuilder().setTypes(types).build();
507     }
508
509     private static void checkUnreachFlows(final List<Flowspec> flows, final FlowspecType icmpType,
510             final FlowspecType icmpCode, final TcpFlagsCase tcp,
511             final PacketLengthCase packet, final FlowspecType dscp, final FlowspecType fragment) {
512         assertEquals(6, flows.size());
513         assertEquals(icmpType, flows.get(0).getFlowspecType());
514         assertEquals(icmpCode, flows.get(1).getFlowspecType());
515         assertEquals(tcp, flows.get(2).getFlowspecType());
516         assertEquals(packet, flows.get(3).getFlowspecType());
517         assertEquals(dscp, flows.get(4).getFlowspecType());
518         assertEquals(fragment, flows.get(5).getFlowspecType());
519     }
520
521     @Test
522     public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
523         final List<Flowspec> fs = new ArrayList<>();
524         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
525
526         final FlowspecBuilder builder = new FlowspecBuilder();
527
528         final FlowspecType icmpType = createIcmpType();
529         builder.setFlowspecType(icmpType);
530         fs.add(builder.build());
531
532         final FlowspecType icmpCode = createIcmpCode();
533         builder.setFlowspecType(icmpCode);
534         fs.add(builder.build());
535
536         final TcpFlagsCase tcp = createTcp();
537         builder.setFlowspecType(tcp);
538         fs.add(builder.build());
539
540         final PacketLengthCase packet = createPackets();
541         builder.setFlowspecType(packet);
542         fs.add(builder.build());
543
544         final FlowspecType dscp = createDscp();
545         builder.setFlowspecType(dscp);
546         fs.add(builder.build());
547
548         final FlowspecType fragment = createFragment();
549         builder.setFlowspecType(fragment);
550         fs.add(builder.build());
551
552         final FlowspecL3vpnIpv4NlriParser parser = new FlowspecL3vpnIpv4NlriParser(
553             this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
554                 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
555
556         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
557         result.setAfi(Ipv4AddressFamily.class);
558         result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
559         parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
560
561         DestinationFlowspecL3vpnIpv4 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
562                 .bgp.flowspec.rev200120.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
563                 .DestinationFlowspecL3vpnIpv4Case) result.getWithdrawnRoutes().getDestinationType())
564                 .getDestinationFlowspecL3vpnIpv4();
565         final List<Flowspec> flows = flowspecDst.getFlowspec();
566         checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
567
568         final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
569
570         mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
571             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
572             .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
573                 .setDestinationFlowspecL3vpnIpv4(
574                     new DestinationFlowspecL3vpnIpv4Builder()
575                         .setRouteDistinguisher(rd)
576                         .setPathId(PATH_ID)
577                         .setFlowspec(fs)
578                         .build()
579                 ).build()
580             ).build()
581         );
582
583         final ByteBuf buffer = Unpooled.buffer();
584         parser.serializeNlri(new Object[] {rd, flows}, PATH_ID, buffer);
585         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
586
587         parser.serializeAttribute(new AttributesBuilder()
588             .addAugmentation(new Attributes2Builder().setMpUnreachNlri(mp.build()).build())
589             .build(), buffer);
590         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
591
592         assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 "
593                 + "or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 "
594                 + "AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ",
595                 this.fsParser.stringNlri(flows));
596
597     }
598
599     @Test
600     public void testExtractFlowspecDestPrefix() {
601         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
602                 Builders.mapEntryBuilder();
603         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
604         entry.withChild(Builders.unkeyedListBuilder()
605             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
606             .withChild(Builders.unkeyedListEntryBuilder()
607                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
608                 .withChild(Builders.choiceBuilder()
609                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
610                     .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID)
611                         .withValue("127.0.0.5/32").build()).build()).build()).build());
612
613         final FlowspecBuilder expectedFS = new FlowspecBuilder();
614         expectedFS.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(
615             new Ipv4Prefix("127.0.0.5/32")).build());
616         final List<Flowspec> expected = new ArrayList<>();
617         expected.add(expectedFS.build());
618         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
619     }
620
621     @Test
622     public void testExtractFlowspecSourcePrefix() {
623         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
624                 Builders.mapEntryBuilder();
625         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
626         entry.withChild(Builders.unkeyedListBuilder()
627             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
628             .withChild(Builders.unkeyedListEntryBuilder()
629                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
630                 .withChild(Builders.choiceBuilder()
631                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
632                     .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID)
633                         .withValue("127.0.0.6/32").build()).build()).build()).build());
634
635         final FlowspecBuilder expectedFS = new FlowspecBuilder();
636         expectedFS.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32"))
637             .build());
638         final List<Flowspec> expected = new ArrayList<>();
639         expected.add(expectedFS.build());
640         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
641     }
642
643     @Test
644     public void testExtractFlowspecProtocolIps() {
645         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
646                 Builders.mapEntryBuilder();
647         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
648         entry.withChild(Builders.unkeyedListBuilder()
649             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
650             .withChild(Builders.unkeyedListEntryBuilder()
651                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
652                 .withChild(Builders.choiceBuilder()
653                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
654                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
655                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
656                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
657                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
658                                     AbstractOperandParser.AND_BIT_VALUE)).build())
659                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
660                                 .withValue(Uint8.valueOf(100)).build()).build())
661                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
662                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
663                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
664                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
665                                 .withValue(Uint8.valueOf(200)).build()).build())
666                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
667                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
668                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
669                                     AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE))
670                                 .build())
671                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
672                                 .withValue(Uint8.valueOf(240)).build()).build())
673                         .build()).build()).build()).build());
674
675         final FlowspecBuilder expectedFS = new FlowspecBuilder()
676                 .setFlowspecType(new ProtocolIpCaseBuilder()
677                     .setProtocolIps(Lists.newArrayList(new ProtocolIpsBuilder()
678                         .setValue(Uint8.valueOf(100))
679                         .setOp(new NumericOperand(true, true, false, false, false))
680                         .build(), new ProtocolIpsBuilder()
681                         .setValue(Uint8.valueOf(200))
682                         .setOp(new NumericOperand(true, false, false, false, false))
683                         .build(), new ProtocolIpsBuilder()
684                         .setValue(Uint8.valueOf(240))
685                         .setOp(new NumericOperand(true, true, true, false, false))
686                         .build()))
687                     .build());
688         final List<Flowspec> expected = new ArrayList<>();
689         expected.add(expectedFS.build());
690         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
691     }
692
693     @Test
694     public void testExtractFlowspecPorts() {
695         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
696                 Builders.mapEntryBuilder();
697         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
698         entry.withChild(Builders.unkeyedListBuilder()
699             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
700             .withChild(Builders.unkeyedListEntryBuilder()
701                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
702                 .withChild(Builders.choiceBuilder()
703                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
704                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
705                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
706                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
707                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
708                                     AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE))
709                                 .build())
710                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
711                                 .withValue(Uint16.valueOf(100)).build()).build())
712                         .build()).build()).build()).build());
713
714         final FlowspecBuilder expectedFS = new FlowspecBuilder()
715                 .setFlowspecType(new PortCaseBuilder()
716                     .setPorts(Lists.newArrayList(new PortsBuilder()
717                         .setValue(Uint16.valueOf(100))
718                         .setOp(new NumericOperand(true, true, false, false, true))
719                         .build()))
720                     .build());
721         final List<Flowspec> expected = new ArrayList<>();
722         expected.add(expectedFS.build());
723         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
724     }
725
726     @Test
727     public void testExtractFlowspecDestinationPorts() {
728         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
729                 Builders.mapEntryBuilder();
730         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
731         entry.withChild(Builders.unkeyedListBuilder()
732             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
733             .withChild(Builders.unkeyedListEntryBuilder()
734                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
735                 .withChild(Builders.choiceBuilder()
736                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
737                     .withChild(Builders.unkeyedListBuilder()
738                         .withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PORT_NID)
739                         .withChild(Builders.unkeyedListEntryBuilder()
740                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
741                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
742                                 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
743                                     AbstractNumericOperandParser.EQUALS_VALUE)).build())
744                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
745                                 .withValue(Uint16.valueOf(1024)).build()).build())
746                         .build()).build()).build()).build());
747         final FlowspecBuilder expectedFS = new FlowspecBuilder();
748         expectedFS.setFlowspecType(new DestinationPortCaseBuilder()
749             .setDestinationPorts(Lists.newArrayList(new DestinationPortsBuilder()
750                 .setValue(Uint16.valueOf(1024))
751                 .setOp(new NumericOperand(false, true, true, false, false))
752                 .build()))
753             .build());
754         final List<Flowspec> expected = new ArrayList<>();
755         expected.add(expectedFS.build());
756         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
757     }
758
759     @Test
760     public void testExtractFlowspecSourcePorts() {
761         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
762                 Builders.mapEntryBuilder();
763         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
764         entry.withChild(Builders.unkeyedListBuilder()
765             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
766             .withChild(Builders.unkeyedListEntryBuilder()
767                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
768                 .withChild(Builders.choiceBuilder()
769                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
770                     .withChild(Builders.unkeyedListBuilder()
771                         .withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PORT_NID)
772                         .withChild(Builders.unkeyedListEntryBuilder()
773                             .withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
774                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
775                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
776                                     AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
777                                     AbstractNumericOperandParser.GREATER_THAN_VALUE,
778                                     AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
779                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
780                                 .withValue(Uint16.valueOf(8080)).build()).build())
781                         .build()).build()).build()).build());
782         final FlowspecBuilder expectedFS = new FlowspecBuilder();
783         expectedFS.setFlowspecType(new SourcePortCaseBuilder()
784             .setSourcePorts(Lists.newArrayList(new SourcePortsBuilder()
785                 .setValue(Uint16.valueOf(8080))
786                 .setOp(new NumericOperand(true, true, true, true, true))
787                 .build()))
788             .build());
789         final List<Flowspec> expected = new ArrayList<>();
790         expected.add(expectedFS.build());
791         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
792     }
793
794     @Test
795     public void testExtractFlowspecSourceTypes() {
796         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
797                 Builders.mapEntryBuilder();
798         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
799         entry.withChild(Builders.unkeyedListBuilder()
800             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
801             .withChild(Builders.unkeyedListEntryBuilder()
802                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
803                 .withChild(Builders.choiceBuilder()
804                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
805                     .withChild(Builders.unkeyedListBuilder()
806                         .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_TYPE_NID)
807                         .withChild(Builders.unkeyedListEntryBuilder()
808                             .withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
809                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
810                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
811                                     AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
812                                     AbstractNumericOperandParser.GREATER_THAN_VALUE,
813                                     AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
814                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
815                                 .withValue(Uint8.valueOf(22)).build()).build())
816                         .build()).build()).build()).build());
817         final FlowspecBuilder expectedFS = new FlowspecBuilder();
818         expectedFS.setFlowspecType(new IcmpTypeCaseBuilder()
819             .setTypes(Lists.newArrayList(new TypesBuilder()
820                 .setValue(Uint8.valueOf(22))
821                 .setOp(new NumericOperand(true, true, true, true, true))
822                 .build()))
823             .build());
824         final List<Flowspec> expected = new ArrayList<>();
825         expected.add(expectedFS.build());
826         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
827     }
828
829     @Test
830     public void testExtractFlowspecSourceCodes() {
831         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
832                 Builders.mapEntryBuilder();
833         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
834         entry.withChild(Builders.unkeyedListBuilder()
835             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
836             .withChild(Builders.unkeyedListEntryBuilder()
837                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
838                 .withChild(Builders.choiceBuilder()
839                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
840                     .withChild(Builders.unkeyedListBuilder()
841                         .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_CODE_NID)
842                         .withChild(Builders.unkeyedListEntryBuilder()
843                             .withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
844                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
845                                 .withValue(Collections.emptySet()).build())
846                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
847                                 .withValue(Uint8.valueOf(23)).build()).build())
848                         .build()).build()).build()).build());
849         final FlowspecBuilder expectedFS = new FlowspecBuilder();
850         expectedFS.setFlowspecType(new IcmpCodeCaseBuilder()
851             .setCodes(Lists.newArrayList(new CodesBuilder()
852                 .setValue(Uint8.valueOf(23))
853                 .setOp(new NumericOperand(false, false, false, false, false))
854                 .build()))
855             .build());
856         final List<Flowspec> expected = new ArrayList<>();
857         expected.add(expectedFS.build());
858         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
859     }
860
861     @Test
862     public void testExtractFlowspecSourceTcpFlags() {
863         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
864                 Builders.mapEntryBuilder();
865         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
866         entry.withChild(Builders.unkeyedListBuilder()
867             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
868             .withChild(Builders.unkeyedListEntryBuilder()
869                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
870                 .withChild(Builders.choiceBuilder()
871                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
872                     .withChild(Builders.unkeyedListBuilder()
873                         .withNodeIdentifier(AbstractFlowspecNlriParser.TCP_FLAGS_NID)
874                         .withChild(Builders.unkeyedListEntryBuilder()
875                             .withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
876                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
877                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
878                                     AbstractOperandParser.END_OF_LIST_VALUE)).build())
879                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
880                                 .withValue(Uint16.valueOf(99)).build()).build())
881                         .build()).build()).build()).build());
882         final FlowspecBuilder expectedFS = new FlowspecBuilder();
883         expectedFS.setFlowspecType(new TcpFlagsCaseBuilder().setTcpFlags(Lists.newArrayList(new TcpFlagsBuilder()
884             .setValue(Uint16.valueOf(99)).setOp(new BitmaskOperand(true, true, false, false)).build())).build());
885         final List<Flowspec> expected = new ArrayList<>();
886         expected.add(expectedFS.build());
887         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
888     }
889
890     @Test
891     public void testExtractFlowspecPacketLengths() {
892         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
893                 Builders.mapEntryBuilder();
894         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
895         entry.withChild(Builders.unkeyedListBuilder()
896             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
897             .withChild(Builders.unkeyedListEntryBuilder()
898                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
899                 .withChild(Builders.choiceBuilder()
900                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
901                     .withChild(Builders.unkeyedListBuilder()
902                         .withNodeIdentifier(AbstractFlowspecNlriParser.PACKET_LENGTHS_NID)
903                         .withChild(Builders.unkeyedListEntryBuilder()
904                             .withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
905                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
906                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
907                                     AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
908                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
909                                 .withValue(Uint16.valueOf(101)).build()).build())
910                         .build()).build()).build()).build());
911         final FlowspecBuilder expectedFS = new FlowspecBuilder();
912         expectedFS.setFlowspecType(new PacketLengthCaseBuilder().setPacketLengths(Lists.newArrayList(
913             new PacketLengthsBuilder().setValue(Uint16.valueOf(101)).setOp(
914                 new NumericOperand(true, false, false, true, false)).build())).build());
915         final List<Flowspec> expected = new ArrayList<>();
916         expected.add(expectedFS.build());
917         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
918     }
919
920     @Test
921     public void testExtractFlowspecDscps() {
922         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
923                 Builders.mapEntryBuilder();
924         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
925         entry.withChild(Builders.unkeyedListBuilder()
926             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
927             .withChild(Builders.unkeyedListEntryBuilder()
928                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
929                 .withChild(Builders.choiceBuilder()
930                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
931                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
932                         .withChild(Builders.unkeyedListEntryBuilder()
933                             .withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
934                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
935                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
936                                     AbstractOperandParser.END_OF_LIST_VALUE,
937                                     AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
938                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
939                                 .withValue(Uint8.valueOf(15)).build()).build())
940                         .build()).build()).build()).build());
941         final FlowspecBuilder expectedFS = new FlowspecBuilder();
942         expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(Lists.newArrayList(new DscpsBuilder().setValue(
943             new Dscp(Uint8.valueOf(15))).setOp(new NumericOperand(true, true, false, true, false)).build())).build());
944         final List<Flowspec> expected = new ArrayList<>();
945         expected.add(expectedFS.build());
946         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
947     }
948
949     @Test
950     public void testExtractFlowspecFragments() {
951         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
952                 Builders.mapEntryBuilder();
953         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
954         entry.withChild(Builders.unkeyedListBuilder()
955             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
956             .withChild(Builders.unkeyedListEntryBuilder()
957                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
958                 .withChild(Builders.choiceBuilder()
959                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
960                     .withChild(Builders.unkeyedListBuilder()
961                         .withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
962                         .withChild(Builders.unkeyedListEntryBuilder()
963                             .withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
964                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
965                                 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
966                                     AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE,
967                                     BitmaskOperandParser.NOT_VALUE)).build())
968                             .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID)
969                                 .withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE,
970                                     AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE,
971                                     AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
972                         .build()).build()).build()).build());
973         final FlowspecBuilder expectedFS = new FlowspecBuilder();
974         expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder()
975             .setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build()))
976             .build());
977         final List<Flowspec> expected = new ArrayList<>();
978         expected.add(expectedFS.build());
979         assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
980     }
981
982     @Test
983     public void testExtractFlowspecRouteDistinguisher() {
984         final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
985                 Builders.mapEntryBuilder();
986         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
987         entry.withChild(
988             Builders.leafBuilder()
989                 .withNodeIdentifier(RD_NID)
990                 .withValue(
991                     RouteDistinguisherBuilder.getDefaultInstance(ROUTE_DISTINGUISHER)
992                 ).build()
993         );
994
995         RouteDistinguisher rd = RouteDistinguisherBuilder.getDefaultInstance(ROUTE_DISTINGUISHER);
996         assertEquals(rd, extractRouteDistinguisher(entry.build(), AbstractFlowspecL3vpnNlriParser.RD_NID));
997     }
998 }
999