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