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 com.google.common.collect.Lists;
16 import com.google.common.collect.Sets;
17 import io.netty.buffer.ByteBuf;
18 import io.netty.buffer.Unpooled;
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.Optional;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.mockito.Mock;
26 import org.mockito.MockitoAnnotations;
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.rev180329.BitmaskOperand;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.Dscp;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.FlowspecSubsequentAddressFamily;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.Fragment;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.NumericOperand;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.Flowspec;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.FlowspecBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.FlowspecType;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.DestinationPortCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.DscpCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.IcmpCodeCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.IcmpTypeCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PacketLengthCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PacketLengthCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PortCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PortCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.SourcePortCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.TcpFlagsCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.TcpFlagsCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPorts;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPortsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.dscp._case.Dscps;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.dscp._case.DscpsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.fragment._case.Fragments;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.fragment._case.FragmentsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.code._case.Codes;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.code._case.CodesBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.type._case.Types;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.type._case.TypesBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengths;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengthsBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.port._case.Ports;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.port._case.PortsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePorts;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePortsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlags;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlagsBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCaseBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCaseBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCaseBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIps;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIpsBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.ipv4.DestinationFlowspecIpv4Builder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.ipv4.route.FlowspecRoute;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.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.rev180329.PathId;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.AttributesBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1Builder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2Builder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlri;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
95 import org.opendaylight.yangtools.yang.common.Uint16;
96 import org.opendaylight.yangtools.yang.common.Uint8;
97 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
98 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
99 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
100 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
101 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
103 public class SimpleFlowspecIpv4NlriParserTest {
105 private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
107 static final PathId PATH_ID = new PathId(1L);
109 private PeerSpecificParserConstraint constraint;
111 private MultiPathSupport muliPathSupport;
113 private static final byte[] REACHED_NLRI = new byte[] {
114 0x21, // NLRI length: 33
115 01, 0x20, 0x0a, 00, 01, 00,
116 02, 0x20, 01, 02, 03, 04,
118 04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
119 05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
120 06, (byte) 0x91, 0x1f, (byte) 0x90
123 private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
125 0x21, // NLRI length: 33
126 01, 0x20, 0x0a, 00, 01, 00,
127 02, 0x20, 01, 02, 03, 04,
129 04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
130 05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
131 06, (byte) 0x91, 0x1f, (byte) 0x90
134 private static final byte[] REACHED_NLRI_BATCHED = new byte[] {
135 0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xf5, 0x65,
136 0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xda, (byte) 0xc4,
137 0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xd8, (byte) 0xc3
140 private static final byte[] UNREACHED_NLRI = new byte[] {
141 0x1B, // NLRI length: 27
142 07, 4, 2, (byte) 0x84, 3,
143 0x08, 4, 04, (byte) 0x80, 05,
144 0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
145 0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
146 0x0b, (byte) 0x82, 0x2a,
147 0x0c, (byte) 0x81, (byte) 0x0e
150 private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
152 0x1B, // NLRI length: 27
153 07, 4, 2, (byte) 0x84, 3,
154 0x08, 4, 04, (byte) 0x80, 05,
155 0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
156 0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
157 0x0b, (byte) 0x82, 0x2a,
158 0x0c, (byte) 0x81, (byte) 0x0e
161 private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
162 private final FlowspecActivator fsa = new FlowspecActivator(this.flowspecContext);
163 private final SimpleFlowspecIpv4NlriParser fsParser = new SimpleFlowspecIpv4NlriParser(
164 flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
165 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
168 public void setUp() {
169 MockitoAnnotations.initMocks(this);
170 doReturn(Optional.of(this.muliPathSupport)).when(this.constraint).getPeerConstraint(any());
171 doReturn(true).when(this.muliPathSupport).isTableTypeSupported(any());
175 public void testParseMpReachNlri() throws BGPParsingException {
176 final List<Flowspec> fs = new ArrayList<>();
177 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
179 final FlowspecBuilder builder = new FlowspecBuilder();
180 final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(
181 new Ipv4Prefix("10.0.1.0/32")).build();
182 builder.setFlowspecType(destinationPrefix);
183 fs.add(builder.build());
184 final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder()
185 .setSourcePrefix(new Ipv4Prefix("1.2.3.4/32")).build();
186 builder.setFlowspecType(sourcePrefix);
187 fs.add(builder.build());
189 final FlowspecType prots = createProts();
190 builder.setFlowspecType(prots);
191 fs.add(builder.build());
193 final PortCase ps = createPorts();
194 builder.setFlowspecType(ps);
195 fs.add(builder.build());
197 final FlowspecType dps = createDps();
198 builder.setFlowspecType(dps);
199 fs.add(builder.build());
201 final FlowspecType sps = createSps();
202 builder.setFlowspecType(sps);
203 fs.add(builder.build());
205 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
206 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329
207 .update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
208 .setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder().setFlowspec(fs).build())
211 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
212 flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
213 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
215 final MpReachNlriBuilder result = new MpReachNlriBuilder();
216 result.setAfi(Ipv4AddressFamily.class);
217 result.setSafi(FlowspecSubsequentAddressFamily.class);
218 parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result, null);
220 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
221 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase)
222 result.getAdvertizedRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
223 testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
225 final ByteBuf buffer = Unpooled.buffer();
226 parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder()
227 .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(), buffer);
228 assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
230 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 "
231 + "is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where "
232 + "destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ",
233 this.fsParser.stringNlri(flows));
236 private static void testFlows(final List<Flowspec> flows, final DestinationPrefixCase destinationPrefix,
237 final SourcePrefixCase sourcePrefix, final FlowspecType prots, final PortCase ps, final FlowspecType dps,
238 final FlowspecType sps) {
239 assertEquals(6, flows.size());
240 assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
241 assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
242 assertEquals(prots, flows.get(2).getFlowspecType());
243 assertEquals(ps, flows.get(3).getFlowspecType());
244 assertEquals(dps, flows.get(4).getFlowspecType());
245 assertEquals(sps, flows.get(5).getFlowspecType());
248 private static FlowspecType createSps() {
249 final List<SourcePorts> sports = Lists.newArrayList(new SourcePortsBuilder().setOp(
250 new NumericOperand(false, true, true, false, false)).setValue(8080).build());
251 return new SourcePortCaseBuilder().setSourcePorts(sports).build();
254 private static FlowspecType createProts() {
255 final List<ProtocolIps> protocols = Lists.newArrayList(new ProtocolIpsBuilder().setOp(
256 new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
257 return new ProtocolIpCaseBuilder().setProtocolIps(protocols).build();
260 private static FlowspecType createDps() {
261 final List<DestinationPorts> destports = Lists.newArrayList(new DestinationPortsBuilder().setOp(
262 new NumericOperand(false, false, false, true, false)).setValue(4089).build(),
263 new DestinationPortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(179)
265 return new DestinationPortCaseBuilder().setDestinationPorts(destports).build();
269 public void testParseMpReachNlriConstraint() throws BGPParsingException {
270 final List<Flowspec> fs = new ArrayList<>();
271 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
273 final FlowspecBuilder builder = new FlowspecBuilder();
274 final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(
275 new Ipv4Prefix("10.0.1.0/32")).build();
276 builder.setFlowspecType(destinationPrefix);
277 fs.add(builder.build());
278 final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder().setSourcePrefix(
279 new Ipv4Prefix("1.2.3.4/32")).build();
280 builder.setFlowspecType(sourcePrefix);
281 fs.add(builder.build());
283 final FlowspecType prots = createProts();
284 builder.setFlowspecType(prots);
285 fs.add(builder.build());
287 final PortCase ps = createPorts();
288 builder.setFlowspecType(ps);
289 fs.add(builder.build());
291 final FlowspecType dps = createDps();
292 builder.setFlowspecType(dps);
293 fs.add(builder.build());
295 final FlowspecType sps = createSps();
296 builder.setFlowspecType(sps);
297 fs.add(builder.build());
299 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
300 .opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes
301 .destination.type.DestinationFlowspecCaseBuilder()
302 .setDestinationFlowspecIpv4(
303 new DestinationFlowspecIpv4Builder()
311 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
312 flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
313 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
315 final MpReachNlriBuilder result = new MpReachNlriBuilder();
316 result.setAfi(Ipv4AddressFamily.class);
317 result.setSafi(FlowspecSubsequentAddressFamily.class);
318 parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
320 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
321 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase)
322 result.getAdvertizedRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
323 testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
325 final ByteBuf buffer = Unpooled.buffer();
326 parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
327 new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(),
329 assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
331 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 "
332 + "is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where "
333 + "destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ",
334 this.fsParser.stringNlri(flows));
337 private static PortCase createPorts() {
338 final List<Ports> ports = Lists.newArrayList(
339 new PortsBuilder().setOp(new NumericOperand(false, false, true, true, false)).setValue(137).build(),
340 new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(139).build(),
341 new PortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(8080).build());
343 return new PortCaseBuilder().setPorts(ports).build();
347 public void testParseMpUnreachNlri() throws BGPParsingException {
348 final List<Flowspec> fs = new ArrayList<>();
349 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
351 final FlowspecBuilder builder = new FlowspecBuilder();
353 final FlowspecType icmpType = createIcmpType();
354 builder.setFlowspecType(icmpType);
355 fs.add(builder.build());
357 final FlowspecType icmpCode = createIcmpCode();
358 builder.setFlowspecType(icmpCode);
359 fs.add(builder.build());
361 final TcpFlagsCase tcp = createTcp();
362 builder.setFlowspecType(tcp);
363 fs.add(builder.build());
365 final PacketLengthCase packet = createPackets();
366 builder.setFlowspecType(packet);
367 fs.add(builder.build());
369 final FlowspecType dscp = createDscp();
370 builder.setFlowspecType(dscp);
371 fs.add(builder.build());
373 final FlowspecType fragment = createFragment();
374 builder.setFlowspecType(fragment);
375 fs.add(builder.build());
377 mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
378 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
379 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
380 .setDestinationFlowspecIpv4(
381 new DestinationFlowspecIpv4Builder()
388 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
389 this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
390 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
392 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
393 result.setAfi(Ipv4AddressFamily.class);
394 result.setSafi(FlowspecSubsequentAddressFamily.class);
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.bgp.flowspec
398 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase)
399 result.getWithdrawnRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
400 checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
402 final ByteBuf buffer = Unpooled.buffer();
403 parser.serializeNlri(new Object[] {flows}, null, buffer);
404 assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
406 parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
407 new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
408 assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
410 assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 "
411 + "or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 "
412 + "AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ",
413 this.fsParser.stringNlri(flows));
417 private static FlowspecType createFragment() {
418 final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder()
419 .setOp(new BitmaskOperand(false, true, true, false))
420 .setValue(new Fragment(false, true, true, true)).build());
421 return new FragmentCaseBuilder().setFragments(fragments).build();
424 private static FlowspecType createDscp() {
425 final List<Dscps> dscps = Lists.newArrayList(new DscpsBuilder()
426 .setOp(new NumericOperand(false, true, false, true, false))
427 .setValue(new Dscp((short) 42)).build());
428 return new DscpCaseBuilder().setDscps(dscps).build();
431 private static PacketLengthCase createPackets() {
432 final List<PacketLengths> packets = Lists.newArrayList(new PacketLengthsBuilder()
433 .setOp(new NumericOperand(false, true, false, false, true))
434 .setValue(57005).build());
435 return new PacketLengthCaseBuilder().setPacketLengths(packets).build();
438 private static TcpFlagsCase createTcp() {
439 final List<TcpFlags> flags = Lists.newArrayList(
440 new TcpFlagsBuilder().setOp(new BitmaskOperand(false, false, false, true)).setValue(1025).build(),
441 new TcpFlagsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(22193).build());
442 return new TcpFlagsCaseBuilder().setTcpFlags(flags).build();
445 private static FlowspecType createIcmpCode() {
446 final List<Codes> codes = Lists.newArrayList(
447 new CodesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue((short) 4).build(),
448 new CodesBuilder().setOp(new NumericOperand(false, true, false, false, false)).setValue((short) 5).build());
449 return new IcmpCodeCaseBuilder().setCodes(codes).build();
452 private static FlowspecType createIcmpType() {
453 final List<Types> types = Lists.newArrayList(
454 new TypesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue((short) 2).build(),
455 new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue((short) 3).build());
456 return new IcmpTypeCaseBuilder().setTypes(types).build();
459 private static void checkUnreachFlows(final List<Flowspec> flows, final FlowspecType icmpType,
460 final FlowspecType icmpCode, final TcpFlagsCase tcp, final PacketLengthCase packet,
461 final FlowspecType dscp, final FlowspecType fragment) {
462 assertEquals(6, flows.size());
463 assertEquals(icmpType, flows.get(0).getFlowspecType());
464 assertEquals(icmpCode, flows.get(1).getFlowspecType());
465 assertEquals(tcp, flows.get(2).getFlowspecType());
466 assertEquals(packet, flows.get(3).getFlowspecType());
467 assertEquals(dscp, flows.get(4).getFlowspecType());
468 assertEquals(fragment, flows.get(5).getFlowspecType());
472 public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
473 final List<Flowspec> fs = new ArrayList<>();
474 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
476 final FlowspecBuilder builder = new FlowspecBuilder();
478 final FlowspecType icmpType = createIcmpType();
479 builder.setFlowspecType(icmpType);
480 fs.add(builder.build());
482 final FlowspecType icmpCode = createIcmpCode();
483 builder.setFlowspecType(icmpCode);
484 fs.add(builder.build());
486 final TcpFlagsCase tcp = createTcp();
487 builder.setFlowspecType(tcp);
488 fs.add(builder.build());
490 final PacketLengthCase packet = createPackets();
491 builder.setFlowspecType(packet);
492 fs.add(builder.build());
494 final FlowspecType dscp = createDscp();
495 builder.setFlowspecType(dscp);
496 fs.add(builder.build());
498 final FlowspecType fragment = createFragment();
499 builder.setFlowspecType(fragment);
500 fs.add(builder.build());
502 mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
503 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
504 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
505 .setDestinationFlowspecIpv4(
506 new DestinationFlowspecIpv4Builder()
514 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
515 this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
516 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
518 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
519 result.setAfi(Ipv4AddressFamily.class);
520 result.setSafi(FlowspecSubsequentAddressFamily.class);
521 parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
523 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
524 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase)
525 result.getWithdrawnRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
526 checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
529 final ByteBuf buffer = Unpooled.buffer();
530 parser.serializeNlri(new Object[] {flows}, PATH_ID, buffer);
531 assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
533 parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
534 new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
535 assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
537 assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 "
538 + "or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 "
539 + "AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ",
540 this.fsParser.stringNlri(flows));
545 public void testExtractFlowspecDestPrefix() {
546 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
547 Builders.mapEntryBuilder();
548 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
549 entry.withChild(Builders.unkeyedListBuilder()
550 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
551 .withChild(Builders.unkeyedListEntryBuilder()
552 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
553 .withChild(Builders.choiceBuilder()
554 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
555 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID)
556 .withValue("127.0.0.5/32").build()).build()).build()).build());
558 final FlowspecBuilder expectedFS = new FlowspecBuilder();
559 expectedFS.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(
560 new Ipv4Prefix("127.0.0.5/32")).build());
561 final List<Flowspec> expected = new ArrayList<>();
562 expected.add(expectedFS.build());
563 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
567 public void testExtractFlowspecSourcePrefix() {
568 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
569 Builders.mapEntryBuilder();
570 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
571 entry.withChild(Builders.unkeyedListBuilder()
572 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
573 .withChild(Builders.unkeyedListEntryBuilder()
574 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
575 .withChild(Builders.choiceBuilder()
576 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
577 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID)
578 .withValue("127.0.0.6/32").build()).build()).build()).build());
580 final FlowspecBuilder expectedFS = new FlowspecBuilder();
581 expectedFS.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32"))
583 final List<Flowspec> expected = new ArrayList<>();
584 expected.add(expectedFS.build());
585 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
589 public void testExtractFlowspecProtocolIps() {
590 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
591 Builders.mapEntryBuilder();
592 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
593 entry.withChild(Builders.unkeyedListBuilder()
594 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
595 .withChild(Builders.unkeyedListEntryBuilder()
596 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
597 .withChild(Builders.choiceBuilder()
598 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
599 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
600 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
601 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
602 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
603 AbstractOperandParser.AND_BIT_VALUE)).build())
604 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
605 .withValue(Uint8.valueOf(100)).build()).build())
606 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
607 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
608 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
609 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
610 .withValue(Uint8.valueOf(200)).build()).build())
611 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
612 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
613 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
614 AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE))
616 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
617 .withValue(Uint8.valueOf(240)).build()).build())
618 .build()).build()).build()).build());
620 final FlowspecBuilder expectedFS = new FlowspecBuilder();
621 expectedFS.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(
623 new ProtocolIpsBuilder().setValue((short) 100).setOp(
624 new NumericOperand(true, true, false, false, false)).build(),
625 new ProtocolIpsBuilder().setValue((short) 200).setOp(
626 new NumericOperand(true, false, false, false, false)).build(),
627 new ProtocolIpsBuilder().setValue((short) 240).setOp(
628 new NumericOperand(true, true, true, false, false)).build())).build());
629 final List<Flowspec> expected = new ArrayList<>();
630 expected.add(expectedFS.build());
631 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
635 public void testExtractFlowspecPorts() {
636 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
637 Builders.mapEntryBuilder();
638 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
639 entry.withChild(Builders.unkeyedListBuilder()
640 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
641 .withChild(Builders.unkeyedListEntryBuilder()
642 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
643 .withChild(Builders.choiceBuilder()
644 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
645 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
646 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
647 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
648 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
649 AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE))
651 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
652 .withValue(Uint16.valueOf(100)).build()).build())
653 .build()).build()).build()).build());
655 final FlowspecBuilder expectedFS = new FlowspecBuilder();
656 expectedFS.setFlowspecType(new PortCaseBuilder().setPorts(Lists.newArrayList(new PortsBuilder()
657 .setValue(100).setOp(new NumericOperand(true, true, false, false, true)).build())).build());
658 final List<Flowspec> expected = new ArrayList<>();
659 expected.add(expectedFS.build());
660 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
664 public void testExtractFlowspecDestinationPorts() {
665 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
666 Builders.mapEntryBuilder();
667 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
668 entry.withChild(Builders.unkeyedListBuilder()
669 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
670 .withChild(Builders.unkeyedListEntryBuilder()
671 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
672 .withChild(Builders.choiceBuilder()
673 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
674 .withChild(Builders.unkeyedListBuilder()
675 .withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PORT_NID)
676 .withChild(Builders.unkeyedListEntryBuilder()
677 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
678 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
679 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
680 AbstractNumericOperandParser.EQUALS_VALUE)).build())
681 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
682 .withValue(Uint16.valueOf(1024)).build()).build())
683 .build()).build()).build()).build());
684 final FlowspecBuilder expectedFS = new FlowspecBuilder();
685 expectedFS.setFlowspecType(new DestinationPortCaseBuilder().setDestinationPorts(Lists.newArrayList(
686 new DestinationPortsBuilder().setValue(1024).setOp(new NumericOperand(false, true, true, false, false))
688 final List<Flowspec> expected = new ArrayList<>();
689 expected.add(expectedFS.build());
690 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
694 public void testExtractFlowspecSourcePorts() {
695 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
696 Builders.mapEntryBuilder();
697 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
698 entry.withChild(Builders.unkeyedListBuilder()
699 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
700 .withChild(Builders.unkeyedListEntryBuilder()
701 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
702 .withChild(Builders.choiceBuilder()
703 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
704 .withChild(Builders.unkeyedListBuilder()
705 .withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PORT_NID)
706 .withChild(Builders.unkeyedListEntryBuilder()
707 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
708 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
709 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
710 AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
711 AbstractNumericOperandParser.GREATER_THAN_VALUE,
712 AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
713 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
714 .withValue(Uint16.valueOf(8080)).build()).build())
715 .build()).build()).build()).build());
716 final FlowspecBuilder expectedFS = new FlowspecBuilder();
717 expectedFS.setFlowspecType(new SourcePortCaseBuilder().setSourcePorts(Lists.newArrayList(
718 new SourcePortsBuilder().setValue(8080).setOp(new NumericOperand(true, true, true, true, true)).build()))
720 final List<Flowspec> expected = new ArrayList<>();
721 expected.add(expectedFS.build());
722 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
726 public void testExtractFlowspecSourceTypes() {
727 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
728 Builders.mapEntryBuilder();
729 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
730 entry.withChild(Builders.unkeyedListBuilder()
731 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
732 .withChild(Builders.unkeyedListEntryBuilder()
733 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
734 .withChild(Builders.choiceBuilder()
735 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
736 .withChild(Builders.unkeyedListBuilder()
737 .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_TYPE_NID)
738 .withChild(Builders.unkeyedListEntryBuilder()
739 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
740 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
741 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
742 AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
743 AbstractNumericOperandParser.GREATER_THAN_VALUE,
744 AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
745 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
746 .withValue(Uint8.valueOf(22)).build()).build())
747 .build()).build()).build()).build());
748 final FlowspecBuilder expectedFS = new FlowspecBuilder();
749 expectedFS.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(Lists.newArrayList(new TypesBuilder()
750 .setValue((short) 22).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
751 final List<Flowspec> expected = new ArrayList<>();
752 expected.add(expectedFS.build());
753 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
757 public void testExtractFlowspecSourceCodes() {
758 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
759 Builders.mapEntryBuilder();
760 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
761 entry.withChild(Builders.unkeyedListBuilder()
762 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
763 .withChild(Builders.unkeyedListEntryBuilder()
764 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
765 .withChild(Builders.choiceBuilder()
766 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
767 .withChild(Builders.unkeyedListBuilder()
768 .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_CODE_NID)
769 .withChild(Builders.unkeyedListEntryBuilder()
770 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
771 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
772 .withValue(Collections.emptySet()).build())
773 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
774 .withValue(Uint8.valueOf(23)).build()).build())
775 .build()).build()).build()).build());
776 final FlowspecBuilder expectedFS = new FlowspecBuilder();
777 expectedFS.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(Lists.newArrayList(new CodesBuilder()
778 .setValue((short) 23).setOp(new NumericOperand(false, false, false, false, false)).build())).build());
779 final List<Flowspec> expected = new ArrayList<>();
780 expected.add(expectedFS.build());
781 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
785 public void testExtractFlowspecSourceTcpFlags() {
786 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
787 Builders.mapEntryBuilder();
788 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
789 entry.withChild(Builders.unkeyedListBuilder()
790 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
791 .withChild(Builders.unkeyedListEntryBuilder()
792 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
793 .withChild(Builders.choiceBuilder()
794 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
795 .withChild(Builders.unkeyedListBuilder()
796 .withNodeIdentifier(AbstractFlowspecNlriParser.TCP_FLAGS_NID)
797 .withChild(Builders.unkeyedListEntryBuilder()
798 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
799 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
800 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
801 AbstractOperandParser.END_OF_LIST_VALUE)).build())
802 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
803 .withValue(Uint16.valueOf(99)).build()).build())
804 .build()).build()).build()).build());
805 final FlowspecBuilder expectedFS = new FlowspecBuilder();
806 expectedFS.setFlowspecType(new TcpFlagsCaseBuilder().setTcpFlags(Lists.newArrayList(new TcpFlagsBuilder()
807 .setValue(99).setOp(new BitmaskOperand(true, true, false, false)).build())).build());
808 final List<Flowspec> expected = new ArrayList<>();
809 expected.add(expectedFS.build());
810 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
814 public void testExtractFlowspecPacketLengths() {
815 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
816 Builders.mapEntryBuilder();
817 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
818 entry.withChild(Builders.unkeyedListBuilder()
819 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
820 .withChild(Builders.unkeyedListEntryBuilder()
821 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
822 .withChild(Builders.choiceBuilder()
823 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
824 .withChild(Builders.unkeyedListBuilder()
825 .withNodeIdentifier(AbstractFlowspecNlriParser.PACKET_LENGTHS_NID)
826 .withChild(Builders.unkeyedListEntryBuilder()
827 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
828 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
829 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
830 AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
831 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
832 .withValue(Uint16.valueOf(101)).build()).build())
833 .build()).build()).build()).build());
834 final FlowspecBuilder expectedFS = new FlowspecBuilder();
835 expectedFS.setFlowspecType(new PacketLengthCaseBuilder().setPacketLengths(Lists.newArrayList(
836 new PacketLengthsBuilder().setValue(101).setOp(new NumericOperand(true, false, false, true, false))
838 final List<Flowspec> expected = new ArrayList<>();
839 expected.add(expectedFS.build());
840 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
844 public void testExtractFlowspecDscps() {
845 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
846 Builders.mapEntryBuilder();
847 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
848 entry.withChild(Builders.unkeyedListBuilder()
849 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
850 .withChild(Builders.unkeyedListEntryBuilder()
851 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
852 .withChild(Builders.choiceBuilder()
853 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
854 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
855 .withChild(Builders.unkeyedListEntryBuilder()
856 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
857 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
858 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
859 AbstractOperandParser.END_OF_LIST_VALUE,
860 AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
861 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
862 .withValue(Uint8.valueOf(15)).build()).build())
863 .build()).build()).build()).build());
864 final FlowspecBuilder expectedFS = new FlowspecBuilder();
865 expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(Lists.newArrayList(new DscpsBuilder()
866 .setValue(new Dscp((short) 15)).setOp(new NumericOperand(true, true, false, true, false)).build()))
868 final List<Flowspec> expected = new ArrayList<>();
869 expected.add(expectedFS.build());
870 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
874 public void testExtractFlowspecFragments() {
875 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
876 Builders.mapEntryBuilder();
877 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
878 entry.withChild(Builders.unkeyedListBuilder()
879 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
880 .withChild(Builders.unkeyedListEntryBuilder()
881 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
882 .withChild(Builders.choiceBuilder()
883 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
884 .withChild(Builders.unkeyedListBuilder()
885 .withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
886 .withChild(Builders.unkeyedListEntryBuilder()
887 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
888 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
889 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
890 AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE,
891 BitmaskOperandParser.NOT_VALUE)).build())
892 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
893 .withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE,
894 AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE,
895 AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
896 .build()).build()).build()).build());
897 final FlowspecBuilder expectedFS = new FlowspecBuilder();
898 expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder()
899 .setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build()))
901 final List<Flowspec> expected = new ArrayList<>();
902 expected.add(expectedFS.build());
903 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
907 public void testBatchedFlowspecNlri() throws Exception {
908 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
909 flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
910 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
912 final MpReachNlriBuilder result = new MpReachNlriBuilder();
913 result.setAfi(Ipv4AddressFamily.class);
914 result.setSafi(FlowspecSubsequentAddressFamily.class);
916 parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_BATCHED), result, null);
917 final MpReachNlri nlri = result.build();
919 final List<Flowspec> flowspecList = ((DestinationFlowspecCase) nlri.getAdvertizedRoutes().getDestinationType())
920 .getDestinationFlowspecIpv4().getFlowspec();
921 assertEquals(3, flowspecList.size());
922 assertEquals("216.58.245.101/32", ((DestinationPrefixCase) flowspecList.get(0).getFlowspecType())
923 .getDestinationPrefix().getValue());
924 assertEquals("216.58.218.196/32", ((DestinationPrefixCase) flowspecList.get(1).getFlowspecType())
925 .getDestinationPrefix().getValue());
926 assertEquals("216.58.216.195/32", ((DestinationPrefixCase) flowspecList.get(2).getFlowspecType())
927 .getDestinationPrefix().getValue());