2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bgp.flowspec;
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;
15 import io.netty.buffer.ByteBuf;
16 import io.netty.buffer.Unpooled;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.Optional;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.mockito.Mock;
25 import org.mockito.junit.MockitoJUnitRunner;
26 import org.opendaylight.protocol.bgp.flowspec.FlowspecTypeRegistries.SAFI;
27 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractNumericOperandParser;
28 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractOperandParser;
29 import org.opendaylight.protocol.bgp.flowspec.handlers.BitmaskOperandParser;
30 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
31 import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupport;
32 import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
33 import org.opendaylight.protocol.util.ByteArray;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.BitmaskOperand;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.Dscp;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.FlowspecSubsequentAddressFamily;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.Fragment;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.NumericOperand;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.Flowspec;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.FlowspecBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.FlowspecType;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.DestinationPortCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.DscpCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.IcmpCodeCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.IcmpTypeCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.PacketLengthCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.PacketLengthCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.PortCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.PortCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.SourcePortCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.TcpFlagsCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.TcpFlagsCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPorts;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPortsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.dscp._case.Dscps;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.dscp._case.DscpsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.fragment._case.Fragments;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.fragment._case.FragmentsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.icmp.code._case.Codes;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.icmp.code._case.CodesBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.icmp.type._case.Types;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.icmp.type._case.TypesBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengths;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengthsBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.port._case.Ports;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.port._case.PortsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePorts;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePortsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlags;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlagsBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCaseBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCaseBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCaseBuilder;
78 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;
79 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;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.destination.ipv4.DestinationFlowspecIpv4Builder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.flowspec.ipv4.route.FlowspecRoute;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesReachBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesUnreachBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.MpReachNlri;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.MpReachNlriBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.mp.reach.nlri.AdvertizedRoutesBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.MpUnreachNlriBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
93 import org.opendaylight.yangtools.yang.common.Uint16;
94 import org.opendaylight.yangtools.yang.common.Uint32;
95 import org.opendaylight.yangtools.yang.common.Uint8;
96 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
97 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
98 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
100 @RunWith(MockitoJUnitRunner.StrictStubs.class)
101 public class SimpleFlowspecIpv4NlriParserTest {
103 private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
105 static final PathId PATH_ID = new PathId(Uint32.ONE);
107 private PeerSpecificParserConstraint constraint;
109 private MultiPathSupport muliPathSupport;
111 private static final byte[] REACHED_NLRI = new byte[] {
112 0x21, // NLRI length: 33
113 01, 0x20, 0x0a, 00, 01, 00,
114 02, 0x20, 01, 02, 03, 04,
116 04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
117 05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
118 06, (byte) 0x91, 0x1f, (byte) 0x90
121 private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
123 0x21, // NLRI length: 33
124 01, 0x20, 0x0a, 00, 01, 00,
125 02, 0x20, 01, 02, 03, 04,
127 04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
128 05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
129 06, (byte) 0x91, 0x1f, (byte) 0x90
132 private static final byte[] REACHED_NLRI_BATCHED = new byte[] {
133 0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xf5, 0x65,
134 0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xda, (byte) 0xc4,
135 0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xd8, (byte) 0xc3
138 private static final byte[] UNREACHED_NLRI = new byte[] {
139 0x1B, // NLRI length: 27
140 07, 4, 2, (byte) 0x84, 3,
141 0x08, 4, 04, (byte) 0x80, 05,
142 0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
143 0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
144 0x0b, (byte) 0x82, 0x2a,
145 0x0c, (byte) 0x81, (byte) 0x0e
148 private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
150 0x1B, // NLRI length: 27
151 07, 4, 2, (byte) 0x84, 3,
152 0x08, 4, 04, (byte) 0x80, 05,
153 0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
154 0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
155 0x0b, (byte) 0x82, 0x2a,
156 0x0c, (byte) 0x81, (byte) 0x0e
159 private final SimpleFlowspecIpv4NlriParser fsParser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
162 public void setUp() {
163 doReturn(Optional.of(muliPathSupport)).when(constraint).getPeerConstraint(any());
164 doReturn(true).when(muliPathSupport).isTableTypeSupported(any());
168 public void testParseMpReachNlri() throws BGPParsingException {
169 final List<Flowspec> fs = new ArrayList<>();
170 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
172 final FlowspecBuilder builder = new FlowspecBuilder();
173 final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(
174 new Ipv4Prefix("10.0.1.0/32")).build();
175 builder.setFlowspecType(destinationPrefix);
176 fs.add(builder.build());
177 final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder()
178 .setSourcePrefix(new Ipv4Prefix("1.2.3.4/32")).build();
179 builder.setFlowspecType(sourcePrefix);
180 fs.add(builder.build());
182 final FlowspecType prots = createProts();
183 builder.setFlowspecType(prots);
184 fs.add(builder.build());
186 final PortCase ps = createPorts();
187 builder.setFlowspecType(ps);
188 fs.add(builder.build());
190 final FlowspecType dps = createDps();
191 builder.setFlowspecType(dps);
192 fs.add(builder.build());
194 final FlowspecType sps = createSps();
195 builder.setFlowspecType(sps);
196 fs.add(builder.build());
198 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
199 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120
200 .update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
201 .setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder().setFlowspec(fs).build())
204 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
206 final MpReachNlriBuilder result = new MpReachNlriBuilder()
207 .setAfi(Ipv4AddressFamily.VALUE)
208 .setSafi(FlowspecSubsequentAddressFamily.VALUE);
209 parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result, null);
211 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
212 .bgp.flowspec.rev200120.update.attributes.mp.reach.nlri.advertized.routes.destination.type
213 .DestinationFlowspecCase)
214 result.getAdvertizedRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
215 testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
217 final ByteBuf buffer = Unpooled.buffer();
218 parser.serializeAttribute(new AttributesBuilder()
219 .addAugmentation(new AttributesReachBuilder()
220 .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.VALUE).build())
223 assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
226 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 \
227 is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where \
228 destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 \
230 fsParser.stringNlri(flows));
233 private static void testFlows(final List<Flowspec> flows, final DestinationPrefixCase destinationPrefix,
234 final SourcePrefixCase sourcePrefix, final FlowspecType prots, final PortCase ps, final FlowspecType dps,
235 final FlowspecType sps) {
236 assertEquals(6, flows.size());
237 assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
238 assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
239 assertEquals(prots, flows.get(2).getFlowspecType());
240 assertEquals(ps, flows.get(3).getFlowspecType());
241 assertEquals(dps, flows.get(4).getFlowspecType());
242 assertEquals(sps, flows.get(5).getFlowspecType());
245 private static FlowspecType createSps() {
246 final List<SourcePorts> sports = List.of(new SourcePortsBuilder().setOp(
247 new NumericOperand(false, true, true, false, false)).setValue(Uint16.valueOf(8080)).build());
248 return new SourcePortCaseBuilder().setSourcePorts(sports).build();
251 private static FlowspecType createProts() {
252 final List<ProtocolIps> protocols = List.of(new ProtocolIpsBuilder().setOp(
253 new NumericOperand(false, true, true, false, false)).setValue(Uint8.valueOf(6)).build());
254 return new ProtocolIpCaseBuilder().setProtocolIps(protocols).build();
257 private static FlowspecType createDps() {
258 final List<DestinationPorts> destports = List.of(new DestinationPortsBuilder().setOp(
259 new NumericOperand(false, false, false, true, false)).setValue(Uint16.valueOf(4089)).build(),
260 new DestinationPortsBuilder().setOp(new NumericOperand(false, true, true, false, false))
261 .setValue(Uint16.valueOf(179)).build());
262 return new DestinationPortCaseBuilder().setDestinationPorts(destports).build();
266 public void testParseMpReachNlriConstraint() throws BGPParsingException {
267 final List<Flowspec> fs = new ArrayList<>();
268 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
270 final FlowspecBuilder builder = new FlowspecBuilder();
271 final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(
272 new Ipv4Prefix("10.0.1.0/32")).build();
273 builder.setFlowspecType(destinationPrefix);
274 fs.add(builder.build());
275 final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder().setSourcePrefix(
276 new Ipv4Prefix("1.2.3.4/32")).build();
277 builder.setFlowspecType(sourcePrefix);
278 fs.add(builder.build());
280 final FlowspecType prots = createProts();
281 builder.setFlowspecType(prots);
282 fs.add(builder.build());
284 final PortCase ps = createPorts();
285 builder.setFlowspecType(ps);
286 fs.add(builder.build());
288 final FlowspecType dps = createDps();
289 builder.setFlowspecType(dps);
290 fs.add(builder.build());
292 final FlowspecType sps = createSps();
293 builder.setFlowspecType(sps);
294 fs.add(builder.build());
296 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
297 .opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update.attributes.mp.reach.nlri.advertized.routes
298 .destination.type.DestinationFlowspecCaseBuilder()
299 .setDestinationFlowspecIpv4(
300 new DestinationFlowspecIpv4Builder()
308 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
310 final MpReachNlriBuilder result = new MpReachNlriBuilder()
311 .setAfi(Ipv4AddressFamily.VALUE)
312 .setSafi(FlowspecSubsequentAddressFamily.VALUE);
313 parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, constraint);
315 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
316 .bgp.flowspec.rev200120.update.attributes.mp.reach.nlri.advertized.routes.destination.type
317 .DestinationFlowspecCase)
318 result.getAdvertizedRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
319 testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
321 final ByteBuf buffer = Unpooled.buffer();
322 parser.serializeAttribute(new AttributesBuilder()
323 .addAugmentation(new AttributesReachBuilder()
324 .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.VALUE).build())
327 assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
330 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 \
331 is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where \
332 destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 \
334 fsParser.stringNlri(flows));
337 private static PortCase createPorts() {
338 final List<Ports> ports = List.of(
339 new PortsBuilder().setOp(new NumericOperand(false, false, true, true, false)).setValue(Uint16.valueOf(137))
341 new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(Uint16.valueOf(139))
343 new PortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(Uint16.valueOf(8080))
346 return new PortCaseBuilder().setPorts(ports).build();
350 public void testParseMpUnreachNlri() throws BGPParsingException {
351 final List<Flowspec> fs = new ArrayList<>();
353 final FlowspecBuilder builder = new FlowspecBuilder();
355 final FlowspecType icmpType = createIcmpType();
356 builder.setFlowspecType(icmpType);
357 fs.add(builder.build());
359 final FlowspecType icmpCode = createIcmpCode();
360 builder.setFlowspecType(icmpCode);
361 fs.add(builder.build());
363 final TcpFlagsCase tcp = createTcp();
364 builder.setFlowspecType(tcp);
365 fs.add(builder.build());
367 final PacketLengthCase packet = createPackets();
368 builder.setFlowspecType(packet);
369 fs.add(builder.build());
371 final FlowspecType dscp = createDscp();
372 builder.setFlowspecType(dscp);
373 fs.add(builder.build());
375 final FlowspecType fragment = createFragment();
376 builder.setFlowspecType(fragment);
377 fs.add(builder.build());
379 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder()
380 .setAfi(Ipv4AddressFamily.VALUE)
381 .setWithdrawnRoutes(new WithdrawnRoutesBuilder()
382 .setDestinationType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
383 .rev200120.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
384 .DestinationFlowspecCaseBuilder().setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder()
390 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
392 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder()
393 .setAfi(Ipv4AddressFamily.VALUE)
394 .setSafi(FlowspecSubsequentAddressFamily.VALUE);
395 parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result, null);
397 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
398 .bgp.flowspec.rev200120.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
399 .DestinationFlowspecCase)
400 result.getWithdrawnRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
401 checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
403 final ByteBuf buffer = Unpooled.buffer();
404 parser.serializeNlri(flows, null, buffer);
405 assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
407 parser.serializeAttribute(new AttributesBuilder()
408 .addAugmentation(new AttributesUnreachBuilder().setMpUnreachNlri(mp.build()).build())
410 assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
413 all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 \
414 or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 \
415 AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' \
417 fsParser.stringNlri(flows));
420 private static FlowspecType createFragment() {
421 final List<Fragments> fragments = List.of(new FragmentsBuilder()
422 .setOp(new BitmaskOperand(false, true, true, false))
423 .setValue(new Fragment(false, true, true, true)).build());
424 return new FragmentCaseBuilder().setFragments(fragments).build();
427 private static FlowspecType createDscp() {
428 final List<Dscps> dscps = List.of(new DscpsBuilder()
429 .setOp(new NumericOperand(false, true, false, true, false))
430 .setValue(new Dscp(Uint8.valueOf(42))).build());
431 return new DscpCaseBuilder().setDscps(dscps).build();
434 private static PacketLengthCase createPackets() {
435 final List<PacketLengths> packets = List.of(new PacketLengthsBuilder()
436 .setOp(new NumericOperand(false, true, false, false, true))
437 .setValue(Uint16.valueOf(57005)).build());
438 return new PacketLengthCaseBuilder().setPacketLengths(packets).build();
441 private static TcpFlagsCase createTcp() {
442 final List<TcpFlags> flags = List.of(new TcpFlagsBuilder()
443 .setOp(new BitmaskOperand(false, false, false, true)).setValue(Uint16.valueOf(1025))
444 .build(), new TcpFlagsBuilder()
445 .setOp(new BitmaskOperand(false, true, true, false))
446 .setValue(Uint16.valueOf(22193)).build());
447 return new TcpFlagsCaseBuilder().setTcpFlags(flags).build();
450 private static FlowspecType createIcmpCode() {
451 final List<Codes> codes = List.of(new CodesBuilder()
452 .setOp(new NumericOperand(false, false, false, false, true))
453 .setValue(Uint8.valueOf(4))
454 .build(), new CodesBuilder()
455 .setOp(new NumericOperand(false, true, false, false, false))
456 .setValue(Uint8.valueOf(5)).build());
457 return new IcmpCodeCaseBuilder().setCodes(codes).build();
460 private static FlowspecType createIcmpType() {
461 final List<Types> types = List.of(
462 new TypesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue(Uint8.TWO)
464 new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue(Uint8.valueOf(3))
466 return new IcmpTypeCaseBuilder().setTypes(types).build();
469 private static void checkUnreachFlows(final List<Flowspec> flows, final FlowspecType icmpType,
470 final FlowspecType icmpCode, final TcpFlagsCase tcp, final PacketLengthCase packet,
471 final FlowspecType dscp, final FlowspecType fragment) {
472 assertEquals(6, flows.size());
473 assertEquals(icmpType, flows.get(0).getFlowspecType());
474 assertEquals(icmpCode, flows.get(1).getFlowspecType());
475 assertEquals(tcp, flows.get(2).getFlowspecType());
476 assertEquals(packet, flows.get(3).getFlowspecType());
477 assertEquals(dscp, flows.get(4).getFlowspecType());
478 assertEquals(fragment, flows.get(5).getFlowspecType());
482 public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
483 final List<Flowspec> fs = new ArrayList<>();
484 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
486 final FlowspecBuilder builder = new FlowspecBuilder();
488 final FlowspecType icmpType = createIcmpType();
489 builder.setFlowspecType(icmpType);
490 fs.add(builder.build());
492 final FlowspecType icmpCode = createIcmpCode();
493 builder.setFlowspecType(icmpCode);
494 fs.add(builder.build());
496 final TcpFlagsCase tcp = createTcp();
497 builder.setFlowspecType(tcp);
498 fs.add(builder.build());
500 final PacketLengthCase packet = createPackets();
501 builder.setFlowspecType(packet);
502 fs.add(builder.build());
504 final FlowspecType dscp = createDscp();
505 builder.setFlowspecType(dscp);
506 fs.add(builder.build());
508 final FlowspecType fragment = createFragment();
509 builder.setFlowspecType(fragment);
510 fs.add(builder.build());
512 mp.setAfi(Ipv4AddressFamily.VALUE).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
513 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
514 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
515 .setDestinationFlowspecIpv4(
516 new DestinationFlowspecIpv4Builder()
524 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
526 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder()
527 .setAfi(Ipv4AddressFamily.VALUE)
528 .setSafi(FlowspecSubsequentAddressFamily.VALUE);
529 parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, constraint);
531 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
532 .bgp.flowspec.rev200120.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
533 .DestinationFlowspecCase)
534 result.getWithdrawnRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
535 checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
538 final ByteBuf buffer = Unpooled.buffer();
539 parser.serializeNlri(flows, PATH_ID, buffer);
540 assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
542 parser.serializeAttribute(new AttributesBuilder()
543 .addAugmentation(new AttributesUnreachBuilder().setMpUnreachNlri(mp.build()).build())
545 assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
548 all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 \
549 or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 \
550 AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' \
552 fsParser.stringNlri(flows));
556 public void testExtractFlowspecDestPrefix() {
557 final var entry = ImmutableNodes.newMapEntryBuilder();
558 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
559 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
560 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
561 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
562 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
563 .withChild(ImmutableNodes.newChoiceBuilder()
564 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
565 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.DEST_PREFIX_NID, "127.0.0.5/32"))
566 .build()).build()).build());
568 final FlowspecBuilder expectedFS = new FlowspecBuilder();
569 expectedFS.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(
570 new Ipv4Prefix("127.0.0.5/32")).build());
571 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
575 public void testExtractFlowspecSourcePrefix() {
576 final var entry = ImmutableNodes.newMapEntryBuilder();
577 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
578 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
579 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
580 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
581 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
582 .withChild(ImmutableNodes.newChoiceBuilder()
583 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
584 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID, "127.0.0.6/32"))
585 .build()).build()).build());
587 final FlowspecBuilder expectedFS = new FlowspecBuilder();
588 expectedFS.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32"))
590 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
594 public void testExtractFlowspecProtocolIps() {
595 final var entry = ImmutableNodes.newMapEntryBuilder();
596 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
597 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
598 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
599 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
600 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
601 .withChild(ImmutableNodes.newChoiceBuilder()
602 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
603 .withChild(ImmutableNodes.newUnkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
604 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
605 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
606 AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)))
608 ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(100)))
610 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
611 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
612 AbstractOperandParser.AND_BIT_VALUE)))
614 ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(200)))
616 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
617 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
618 AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE,
619 AbstractNumericOperandParser.EQUALS_VALUE)))
621 ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(240)))
623 .build()).build()).build()).build());
625 final FlowspecBuilder expectedFS = new FlowspecBuilder();
626 expectedFS.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(
628 new ProtocolIpsBuilder().setValue(Uint8.valueOf(100)).setOp(
629 new NumericOperand(true, true, false, false, false)).build(),
630 new ProtocolIpsBuilder().setValue(Uint8.valueOf(200)).setOp(
631 new NumericOperand(true, false, false, false, false)).build(),
632 new ProtocolIpsBuilder().setValue(Uint8.valueOf(240)).setOp(
633 new NumericOperand(true, true, true, false, false)).build())).build());
634 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
638 public void testExtractFlowspecPorts() {
639 final var entry = ImmutableNodes.newMapEntryBuilder();
640 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
641 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
642 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
643 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
644 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
645 .withChild(ImmutableNodes.newChoiceBuilder()
646 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
647 .withChild(ImmutableNodes.newUnkeyedListBuilder()
648 .withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
649 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
650 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
651 AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE,
652 AbstractNumericOperandParser.LESS_THAN_VALUE)))
654 ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(100)))
656 .build()).build()).build()).build());
658 final FlowspecBuilder expectedFS = new FlowspecBuilder()
659 .setFlowspecType(new PortCaseBuilder()
660 .setPorts(List.of(new PortsBuilder()
661 .setValue(Uint16.valueOf(100))
662 .setOp(new NumericOperand(true, true, false, false, true))
665 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
669 public void testExtractFlowspecDestinationPorts() {
670 final var entry = ImmutableNodes.newMapEntryBuilder();
671 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
672 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
673 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
674 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
675 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
676 .withChild(ImmutableNodes.newChoiceBuilder()
677 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
678 .withChild(ImmutableNodes.newUnkeyedListBuilder()
679 .withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PORT_NID)
680 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
681 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
682 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
683 AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)))
685 ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(1024)))
687 .build()).build()).build()).build());
688 final FlowspecBuilder expectedFS = new FlowspecBuilder();
689 expectedFS.setFlowspecType(new DestinationPortCaseBuilder()
690 .setDestinationPorts(List.of(new DestinationPortsBuilder()
691 .setValue(Uint16.valueOf(1024))
692 .setOp(new NumericOperand(false, true, true, false, false))
695 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
699 public void testExtractFlowspecSourcePorts() {
700 final var entry = ImmutableNodes.newMapEntryBuilder();
701 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
702 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
703 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
704 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
705 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
706 .withChild(ImmutableNodes.newChoiceBuilder()
707 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
708 .withChild(ImmutableNodes.newUnkeyedListBuilder()
709 .withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PORT_NID)
710 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
711 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
712 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
713 AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE,
714 AbstractNumericOperandParser.EQUALS_VALUE,
715 AbstractNumericOperandParser.GREATER_THAN_VALUE,
716 AbstractNumericOperandParser.LESS_THAN_VALUE)))
718 ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(8080)))
720 .build()).build()).build()).build());
721 final FlowspecBuilder expectedFS = new FlowspecBuilder();
722 expectedFS.setFlowspecType(new SourcePortCaseBuilder()
723 .setSourcePorts(List.of(new SourcePortsBuilder()
724 .setValue(Uint16.valueOf(8080))
725 .setOp(new NumericOperand(true, true, true, true, true))
728 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
732 public void testExtractFlowspecSourceTypes() {
733 final var entry = ImmutableNodes.newMapEntryBuilder();
734 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
735 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
736 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
737 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
738 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
739 .withChild(ImmutableNodes.newChoiceBuilder()
740 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
741 .withChild(ImmutableNodes.newUnkeyedListBuilder()
742 .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_TYPE_NID)
743 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
744 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
745 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
746 AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE,
747 AbstractNumericOperandParser.EQUALS_VALUE,
748 AbstractNumericOperandParser.GREATER_THAN_VALUE,
749 AbstractNumericOperandParser.LESS_THAN_VALUE)))
750 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(22)))
752 .build()).build()).build()).build());
753 final FlowspecBuilder expectedFS = new FlowspecBuilder();
754 expectedFS.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(List.of(new TypesBuilder()
755 .setValue(Uint8.valueOf(22)).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
756 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
760 public void testExtractFlowspecSourceCodes() {
761 final var entry = ImmutableNodes.newMapEntryBuilder();
762 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
763 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
764 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
765 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
766 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
767 .withChild(ImmutableNodes.newChoiceBuilder()
768 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
769 .withChild(ImmutableNodes.newUnkeyedListBuilder()
770 .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_CODE_NID)
771 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
772 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
773 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of()))
774 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(23)))
776 .build()).build()).build()).build());
777 final FlowspecBuilder expectedFS = new FlowspecBuilder();
778 expectedFS.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(List.of(new CodesBuilder()
779 .setValue(Uint8.valueOf(23)).setOp(new NumericOperand(false, false, false, false, false)).build()))
781 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
785 public void testExtractFlowspecSourceTcpFlags() {
786 final var entry = ImmutableNodes.newMapEntryBuilder();
787 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
788 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
789 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
790 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
791 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
792 .withChild(ImmutableNodes.newChoiceBuilder()
793 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
794 .withChild(ImmutableNodes.newUnkeyedListBuilder()
795 .withNodeIdentifier(AbstractFlowspecNlriParser.TCP_FLAGS_NID)
796 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
797 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
798 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
799 AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE)))
801 ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(99)))
803 .build()).build()).build()).build());
804 final FlowspecBuilder expectedFS = new FlowspecBuilder();
805 expectedFS.setFlowspecType(new TcpFlagsCaseBuilder()
806 .setTcpFlags(List.of(new TcpFlagsBuilder()
807 .setValue(Uint16.valueOf(99))
808 .setOp(new BitmaskOperand(true, true, false, false))
811 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
815 public void testExtractFlowspecPacketLengths() {
816 final var entry = ImmutableNodes.newMapEntryBuilder();
817 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
818 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
819 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
820 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
821 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
822 .withChild(ImmutableNodes.newChoiceBuilder()
823 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
824 .withChild(ImmutableNodes.newUnkeyedListBuilder()
825 .withNodeIdentifier(AbstractFlowspecNlriParser.PACKET_LENGTHS_NID)
826 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
827 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
828 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
829 AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)))
831 ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(101)))
833 .build()).build()).build()).build());
834 final FlowspecBuilder expectedFS = new FlowspecBuilder();
835 expectedFS.setFlowspecType(new PacketLengthCaseBuilder()
836 .setPacketLengths(List.of(new PacketLengthsBuilder()
837 .setValue(Uint16.valueOf(101))
838 .setOp(new NumericOperand(true, false, false, true, false))
841 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
845 public void testExtractFlowspecDscps() {
846 final var entry = ImmutableNodes.newMapEntryBuilder();
847 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
848 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
849 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
850 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
851 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
852 .withChild(ImmutableNodes.newChoiceBuilder()
853 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
854 .withChild(ImmutableNodes.newUnkeyedListBuilder()
855 .withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
856 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
857 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
858 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
859 AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE,
860 AbstractNumericOperandParser.GREATER_THAN_VALUE)))
861 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(15)))
863 .build()).build()).build()).build());
864 final FlowspecBuilder expectedFS = new FlowspecBuilder();
865 expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(List.of(new DscpsBuilder()
866 .setValue(new Dscp(Uint8.valueOf(15))).setOp(new NumericOperand(true, true, false, true, false)).build()))
868 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
872 public void testExtractFlowspecFragments() {
873 final var entry = ImmutableNodes.newMapEntryBuilder();
874 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
875 entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
876 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
877 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
878 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
879 .withChild(ImmutableNodes.newChoiceBuilder()
880 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
881 .withChild(ImmutableNodes.newUnkeyedListBuilder()
882 .withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
883 .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
884 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
885 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
886 AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE,
887 BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)))
888 .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Set.of(
889 AbstractFlowspecNlriParser.DO_NOT_VALUE, AbstractFlowspecNlriParser.FIRST_VALUE,
890 AbstractFlowspecNlriParser.IS_A_VALUE, AbstractFlowspecNlriParser.LAST_VALUE)))
892 .build()).build()).build()).build());
893 final FlowspecBuilder expectedFS = new FlowspecBuilder();
894 expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(List.of(new FragmentsBuilder()
895 .setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build()))
897 assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
901 public void testBatchedFlowspecNlri() throws Exception {
902 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
904 final MpReachNlriBuilder result = new MpReachNlriBuilder()
905 .setAfi(Ipv4AddressFamily.VALUE)
906 .setSafi(FlowspecSubsequentAddressFamily.VALUE);
908 parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_BATCHED), result, null);
909 final MpReachNlri nlri = result.build();
911 final List<Flowspec> flowspecList = ((DestinationFlowspecCase) nlri.getAdvertizedRoutes().getDestinationType())
912 .getDestinationFlowspecIpv4().nonnullFlowspec();
913 assertEquals(3, flowspecList.size());
914 assertEquals("216.58.245.101/32", ((DestinationPrefixCase) flowspecList.get(0).getFlowspecType())
915 .getDestinationPrefix().getValue());
916 assertEquals("216.58.218.196/32", ((DestinationPrefixCase) flowspecList.get(1).getFlowspecType())
917 .getDestinationPrefix().getValue());
918 assertEquals("216.58.216.195/32", ((DestinationPrefixCase) flowspecList.get(2).getFlowspecType())
919 .getDestinationPrefix().getValue());