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.Uint32;
97 import org.opendaylight.yangtools.yang.common.Uint8;
98 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
99 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
100 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
101 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
102 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
104 public class SimpleFlowspecIpv4NlriParserTest {
106 private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
108 static final PathId PATH_ID = new PathId(Uint32.ONE);
110 private PeerSpecificParserConstraint constraint;
112 private MultiPathSupport muliPathSupport;
114 private static final byte[] REACHED_NLRI = new byte[] {
115 0x21, // NLRI length: 33
116 01, 0x20, 0x0a, 00, 01, 00,
117 02, 0x20, 01, 02, 03, 04,
119 04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
120 05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
121 06, (byte) 0x91, 0x1f, (byte) 0x90
124 private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
126 0x21, // NLRI length: 33
127 01, 0x20, 0x0a, 00, 01, 00,
128 02, 0x20, 01, 02, 03, 04,
130 04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
131 05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
132 06, (byte) 0x91, 0x1f, (byte) 0x90
135 private static final byte[] REACHED_NLRI_BATCHED = new byte[] {
136 0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xf5, 0x65,
137 0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xda, (byte) 0xc4,
138 0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xd8, (byte) 0xc3
141 private static final byte[] UNREACHED_NLRI = new byte[] {
142 0x1B, // NLRI length: 27
143 07, 4, 2, (byte) 0x84, 3,
144 0x08, 4, 04, (byte) 0x80, 05,
145 0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
146 0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
147 0x0b, (byte) 0x82, 0x2a,
148 0x0c, (byte) 0x81, (byte) 0x0e
151 private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
153 0x1B, // NLRI length: 27
154 07, 4, 2, (byte) 0x84, 3,
155 0x08, 4, 04, (byte) 0x80, 05,
156 0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
157 0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
158 0x0b, (byte) 0x82, 0x2a,
159 0x0c, (byte) 0x81, (byte) 0x0e
162 private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
163 private final FlowspecActivator fsa = new FlowspecActivator(this.flowspecContext);
164 private final SimpleFlowspecIpv4NlriParser fsParser = new SimpleFlowspecIpv4NlriParser(
165 flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
166 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
169 public void setUp() {
170 MockitoAnnotations.initMocks(this);
171 doReturn(Optional.of(this.muliPathSupport)).when(this.constraint).getPeerConstraint(any());
172 doReturn(true).when(this.muliPathSupport).isTableTypeSupported(any());
176 public void testParseMpReachNlri() throws BGPParsingException {
177 final List<Flowspec> fs = new ArrayList<>();
178 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
180 final FlowspecBuilder builder = new FlowspecBuilder();
181 final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(
182 new Ipv4Prefix("10.0.1.0/32")).build();
183 builder.setFlowspecType(destinationPrefix);
184 fs.add(builder.build());
185 final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder()
186 .setSourcePrefix(new Ipv4Prefix("1.2.3.4/32")).build();
187 builder.setFlowspecType(sourcePrefix);
188 fs.add(builder.build());
190 final FlowspecType prots = createProts();
191 builder.setFlowspecType(prots);
192 fs.add(builder.build());
194 final PortCase ps = createPorts();
195 builder.setFlowspecType(ps);
196 fs.add(builder.build());
198 final FlowspecType dps = createDps();
199 builder.setFlowspecType(dps);
200 fs.add(builder.build());
202 final FlowspecType sps = createSps();
203 builder.setFlowspecType(sps);
204 fs.add(builder.build());
206 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
207 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329
208 .update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
209 .setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder().setFlowspec(fs).build())
212 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
213 flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
214 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
216 final MpReachNlriBuilder result = new MpReachNlriBuilder();
217 result.setAfi(Ipv4AddressFamily.class);
218 result.setSafi(FlowspecSubsequentAddressFamily.class);
219 parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result, null);
221 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
222 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase)
223 result.getAdvertizedRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
224 testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
226 final ByteBuf buffer = Unpooled.buffer();
227 parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder()
228 .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(), buffer);
229 assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
231 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 "
232 + "is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where "
233 + "destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ",
234 this.fsParser.stringNlri(flows));
237 private static void testFlows(final List<Flowspec> flows, final DestinationPrefixCase destinationPrefix,
238 final SourcePrefixCase sourcePrefix, final FlowspecType prots, final PortCase ps, final FlowspecType dps,
239 final FlowspecType sps) {
240 assertEquals(6, flows.size());
241 assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
242 assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
243 assertEquals(prots, flows.get(2).getFlowspecType());
244 assertEquals(ps, flows.get(3).getFlowspecType());
245 assertEquals(dps, flows.get(4).getFlowspecType());
246 assertEquals(sps, flows.get(5).getFlowspecType());
249 private static FlowspecType createSps() {
250 final List<SourcePorts> sports = Lists.newArrayList(new SourcePortsBuilder().setOp(
251 new NumericOperand(false, true, true, false, false)).setValue(Uint16.valueOf(8080)).build());
252 return new SourcePortCaseBuilder().setSourcePorts(sports).build();
255 private static FlowspecType createProts() {
256 final List<ProtocolIps> protocols = Lists.newArrayList(new ProtocolIpsBuilder().setOp(
257 new NumericOperand(false, true, true, false, false)).setValue(Uint8.valueOf(6)).build());
258 return new ProtocolIpCaseBuilder().setProtocolIps(protocols).build();
261 private static FlowspecType createDps() {
262 final List<DestinationPorts> destports = Lists.newArrayList(new DestinationPortsBuilder().setOp(
263 new NumericOperand(false, false, false, true, false)).setValue(Uint16.valueOf(4089)).build(),
264 new DestinationPortsBuilder().setOp(new NumericOperand(false, true, true, false, false))
265 .setValue(Uint16.valueOf(179)).build());
266 return new DestinationPortCaseBuilder().setDestinationPorts(destports).build();
270 public void testParseMpReachNlriConstraint() throws BGPParsingException {
271 final List<Flowspec> fs = new ArrayList<>();
272 final MpReachNlriBuilder mp = new MpReachNlriBuilder();
274 final FlowspecBuilder builder = new FlowspecBuilder();
275 final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(
276 new Ipv4Prefix("10.0.1.0/32")).build();
277 builder.setFlowspecType(destinationPrefix);
278 fs.add(builder.build());
279 final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder().setSourcePrefix(
280 new Ipv4Prefix("1.2.3.4/32")).build();
281 builder.setFlowspecType(sourcePrefix);
282 fs.add(builder.build());
284 final FlowspecType prots = createProts();
285 builder.setFlowspecType(prots);
286 fs.add(builder.build());
288 final PortCase ps = createPorts();
289 builder.setFlowspecType(ps);
290 fs.add(builder.build());
292 final FlowspecType dps = createDps();
293 builder.setFlowspecType(dps);
294 fs.add(builder.build());
296 final FlowspecType sps = createSps();
297 builder.setFlowspecType(sps);
298 fs.add(builder.build());
300 mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn
301 .opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes
302 .destination.type.DestinationFlowspecCaseBuilder()
303 .setDestinationFlowspecIpv4(
304 new DestinationFlowspecIpv4Builder()
312 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
313 flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
314 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
316 final MpReachNlriBuilder result = new MpReachNlriBuilder();
317 result.setAfi(Ipv4AddressFamily.class);
318 result.setSafi(FlowspecSubsequentAddressFamily.class);
319 parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
321 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
322 .rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase)
323 result.getAdvertizedRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
324 testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
326 final ByteBuf buffer = Unpooled.buffer();
327 parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
328 new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(),
330 assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
332 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 "
333 + "is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where "
334 + "destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ",
335 this.fsParser.stringNlri(flows));
338 private static PortCase createPorts() {
339 final List<Ports> ports = Lists.newArrayList(
340 new PortsBuilder().setOp(new NumericOperand(false, false, true, true, false)).setValue(Uint16.valueOf(137))
342 new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(Uint16.valueOf(139))
344 new PortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(Uint16.valueOf(8080))
347 return new PortCaseBuilder().setPorts(ports).build();
351 public void testParseMpUnreachNlri() throws BGPParsingException {
352 final List<Flowspec> fs = new ArrayList<>();
353 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
355 final FlowspecBuilder builder = new FlowspecBuilder();
357 final FlowspecType icmpType = createIcmpType();
358 builder.setFlowspecType(icmpType);
359 fs.add(builder.build());
361 final FlowspecType icmpCode = createIcmpCode();
362 builder.setFlowspecType(icmpCode);
363 fs.add(builder.build());
365 final TcpFlagsCase tcp = createTcp();
366 builder.setFlowspecType(tcp);
367 fs.add(builder.build());
369 final PacketLengthCase packet = createPackets();
370 builder.setFlowspecType(packet);
371 fs.add(builder.build());
373 final FlowspecType dscp = createDscp();
374 builder.setFlowspecType(dscp);
375 fs.add(builder.build());
377 final FlowspecType fragment = createFragment();
378 builder.setFlowspecType(fragment);
379 fs.add(builder.build());
381 mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
382 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
383 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
384 .setDestinationFlowspecIpv4(
385 new DestinationFlowspecIpv4Builder()
392 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
393 this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
394 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
396 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
397 result.setAfi(Ipv4AddressFamily.class);
398 result.setSafi(FlowspecSubsequentAddressFamily.class);
399 parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result, null);
401 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
402 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase)
403 result.getWithdrawnRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
404 checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
406 final ByteBuf buffer = Unpooled.buffer();
407 parser.serializeNlri(new Object[] {flows}, null, buffer);
408 assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
410 parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
411 new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
412 assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
414 assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 "
415 + "or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 "
416 + "AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ",
417 this.fsParser.stringNlri(flows));
421 private static FlowspecType createFragment() {
422 final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder()
423 .setOp(new BitmaskOperand(false, true, true, false))
424 .setValue(new Fragment(false, true, true, true)).build());
425 return new FragmentCaseBuilder().setFragments(fragments).build();
428 private static FlowspecType createDscp() {
429 final List<Dscps> dscps = Lists.newArrayList(new DscpsBuilder()
430 .setOp(new NumericOperand(false, true, false, true, false))
431 .setValue(new Dscp(Uint8.valueOf(42))).build());
432 return new DscpCaseBuilder().setDscps(dscps).build();
435 private static PacketLengthCase createPackets() {
436 final List<PacketLengths> packets = Lists.newArrayList(new PacketLengthsBuilder()
437 .setOp(new NumericOperand(false, true, false, false, true))
438 .setValue(Uint16.valueOf(57005)).build());
439 return new PacketLengthCaseBuilder().setPacketLengths(packets).build();
442 private static TcpFlagsCase createTcp() {
443 final List<TcpFlags> flags = Lists.newArrayList(new TcpFlagsBuilder()
444 .setOp(new BitmaskOperand(false, false, false, true)).setValue(Uint16.valueOf(1025))
445 .build(), new TcpFlagsBuilder()
446 .setOp(new BitmaskOperand(false, true, true, false))
447 .setValue(Uint16.valueOf(22193)).build());
448 return new TcpFlagsCaseBuilder().setTcpFlags(flags).build();
451 private static FlowspecType createIcmpCode() {
452 final List<Codes> codes = Lists.newArrayList(new CodesBuilder()
453 .setOp(new NumericOperand(false, false, false, false, true))
454 .setValue(Uint8.valueOf(4))
455 .build(), new CodesBuilder()
456 .setOp(new NumericOperand(false, true, false, false, false))
457 .setValue(Uint8.valueOf(5)).build());
458 return new IcmpCodeCaseBuilder().setCodes(codes).build();
461 private static FlowspecType createIcmpType() {
462 final List<Types> types = Lists.newArrayList(
463 new TypesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue(Uint8.TWO)
465 new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue(Uint8.valueOf(3))
467 return new IcmpTypeCaseBuilder().setTypes(types).build();
470 private static void checkUnreachFlows(final List<Flowspec> flows, final FlowspecType icmpType,
471 final FlowspecType icmpCode, final TcpFlagsCase tcp, final PacketLengthCase packet,
472 final FlowspecType dscp, final FlowspecType fragment) {
473 assertEquals(6, flows.size());
474 assertEquals(icmpType, flows.get(0).getFlowspecType());
475 assertEquals(icmpCode, flows.get(1).getFlowspecType());
476 assertEquals(tcp, flows.get(2).getFlowspecType());
477 assertEquals(packet, flows.get(3).getFlowspecType());
478 assertEquals(dscp, flows.get(4).getFlowspecType());
479 assertEquals(fragment, flows.get(5).getFlowspecType());
483 public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
484 final List<Flowspec> fs = new ArrayList<>();
485 final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
487 final FlowspecBuilder builder = new FlowspecBuilder();
489 final FlowspecType icmpType = createIcmpType();
490 builder.setFlowspecType(icmpType);
491 fs.add(builder.build());
493 final FlowspecType icmpCode = createIcmpCode();
494 builder.setFlowspecType(icmpCode);
495 fs.add(builder.build());
497 final TcpFlagsCase tcp = createTcp();
498 builder.setFlowspecType(tcp);
499 fs.add(builder.build());
501 final PacketLengthCase packet = createPackets();
502 builder.setFlowspecType(packet);
503 fs.add(builder.build());
505 final FlowspecType dscp = createDscp();
506 builder.setFlowspecType(dscp);
507 fs.add(builder.build());
509 final FlowspecType fragment = createFragment();
510 builder.setFlowspecType(fragment);
511 fs.add(builder.build());
513 mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
514 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update
515 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
516 .setDestinationFlowspecIpv4(
517 new DestinationFlowspecIpv4Builder()
525 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
526 this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
527 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
529 final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
530 result.setAfi(Ipv4AddressFamily.class);
531 result.setSafi(FlowspecSubsequentAddressFamily.class);
532 parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
534 final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
535 .rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase)
536 result.getWithdrawnRoutes().getDestinationType()).getDestinationFlowspecIpv4().getFlowspec();
537 checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
540 final ByteBuf buffer = Unpooled.buffer();
541 parser.serializeNlri(new Object[] {flows}, PATH_ID, buffer);
542 assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
544 parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
545 new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
546 assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
548 assertEquals("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' ",
551 this.fsParser.stringNlri(flows));
556 public void testExtractFlowspecDestPrefix() {
557 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
558 Builders.mapEntryBuilder();
559 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
560 entry.withChild(Builders.unkeyedListBuilder()
561 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
562 .withChild(Builders.unkeyedListEntryBuilder()
563 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
564 .withChild(Builders.choiceBuilder()
565 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
566 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID)
567 .withValue("127.0.0.5/32").build()).build()).build()).build());
569 final FlowspecBuilder expectedFS = new FlowspecBuilder();
570 expectedFS.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(
571 new Ipv4Prefix("127.0.0.5/32")).build());
572 final List<Flowspec> expected = new ArrayList<>();
573 expected.add(expectedFS.build());
574 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
578 public void testExtractFlowspecSourcePrefix() {
579 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
580 Builders.mapEntryBuilder();
581 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
582 entry.withChild(Builders.unkeyedListBuilder()
583 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
584 .withChild(Builders.unkeyedListEntryBuilder()
585 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
586 .withChild(Builders.choiceBuilder()
587 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
588 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID)
589 .withValue("127.0.0.6/32").build()).build()).build()).build());
591 final FlowspecBuilder expectedFS = new FlowspecBuilder();
592 expectedFS.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32"))
594 final List<Flowspec> expected = new ArrayList<>();
595 expected.add(expectedFS.build());
596 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
600 public void testExtractFlowspecProtocolIps() {
601 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
602 Builders.mapEntryBuilder();
603 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
604 entry.withChild(Builders.unkeyedListBuilder()
605 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
606 .withChild(Builders.unkeyedListEntryBuilder()
607 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
608 .withChild(Builders.choiceBuilder()
609 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
610 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
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)).build())
615 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
616 .withValue(Uint8.valueOf(100)).build()).build())
617 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
618 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
619 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
620 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
621 .withValue(Uint8.valueOf(200)).build()).build())
622 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
623 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
624 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
625 AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE))
627 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
628 .withValue(Uint8.valueOf(240)).build()).build())
629 .build()).build()).build()).build());
631 final FlowspecBuilder expectedFS = new FlowspecBuilder();
632 expectedFS.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(
634 new ProtocolIpsBuilder().setValue(Uint8.valueOf(100)).setOp(
635 new NumericOperand(true, true, false, false, false)).build(),
636 new ProtocolIpsBuilder().setValue(Uint8.valueOf(200)).setOp(
637 new NumericOperand(true, false, false, false, false)).build(),
638 new ProtocolIpsBuilder().setValue(Uint8.valueOf(240)).setOp(
639 new NumericOperand(true, true, true, false, false)).build())).build());
640 final List<Flowspec> expected = new ArrayList<>();
641 expected.add(expectedFS.build());
642 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
646 public void testExtractFlowspecPorts() {
647 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
648 Builders.mapEntryBuilder();
649 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
650 entry.withChild(Builders.unkeyedListBuilder()
651 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
652 .withChild(Builders.unkeyedListEntryBuilder()
653 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
654 .withChild(Builders.choiceBuilder()
655 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
656 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
657 .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
658 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
659 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
660 AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE))
662 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
663 .withValue(Uint16.valueOf(100)).build()).build())
664 .build()).build()).build()).build());
666 final FlowspecBuilder expectedFS = new FlowspecBuilder()
667 .setFlowspecType(new PortCaseBuilder()
668 .setPorts(Lists.newArrayList(new PortsBuilder()
669 .setValue(Uint16.valueOf(100))
670 .setOp(new NumericOperand(true, true, false, false, true))
673 final List<Flowspec> expected = new ArrayList<>();
674 expected.add(expectedFS.build());
675 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
679 public void testExtractFlowspecDestinationPorts() {
680 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
681 Builders.mapEntryBuilder();
682 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
683 entry.withChild(Builders.unkeyedListBuilder()
684 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
685 .withChild(Builders.unkeyedListEntryBuilder()
686 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
687 .withChild(Builders.choiceBuilder()
688 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
689 .withChild(Builders.unkeyedListBuilder()
690 .withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PORT_NID)
691 .withChild(Builders.unkeyedListEntryBuilder()
692 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
693 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
694 .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
695 AbstractNumericOperandParser.EQUALS_VALUE)).build())
696 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
697 .withValue(Uint16.valueOf(1024)).build()).build())
698 .build()).build()).build()).build());
699 final FlowspecBuilder expectedFS = new FlowspecBuilder();
700 expectedFS.setFlowspecType(new DestinationPortCaseBuilder()
701 .setDestinationPorts(Lists.newArrayList(new DestinationPortsBuilder()
702 .setValue(Uint16.valueOf(1024))
703 .setOp(new NumericOperand(false, true, true, false, false))
706 final List<Flowspec> expected = new ArrayList<>();
707 expected.add(expectedFS.build());
708 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
712 public void testExtractFlowspecSourcePorts() {
713 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
714 Builders.mapEntryBuilder();
715 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
716 entry.withChild(Builders.unkeyedListBuilder()
717 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
718 .withChild(Builders.unkeyedListEntryBuilder()
719 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
720 .withChild(Builders.choiceBuilder()
721 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
722 .withChild(Builders.unkeyedListBuilder()
723 .withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PORT_NID)
724 .withChild(Builders.unkeyedListEntryBuilder()
725 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
726 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
727 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
728 AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
729 AbstractNumericOperandParser.GREATER_THAN_VALUE,
730 AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
731 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
732 .withValue(Uint16.valueOf(8080)).build()).build())
733 .build()).build()).build()).build());
734 final FlowspecBuilder expectedFS = new FlowspecBuilder();
735 expectedFS.setFlowspecType(new SourcePortCaseBuilder()
736 .setSourcePorts(Lists.newArrayList(new SourcePortsBuilder()
737 .setValue(Uint16.valueOf(8080))
738 .setOp(new NumericOperand(true, true, true, true, true))
741 final List<Flowspec> expected = new ArrayList<>();
742 expected.add(expectedFS.build());
743 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
747 public void testExtractFlowspecSourceTypes() {
748 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
749 Builders.mapEntryBuilder();
750 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
751 entry.withChild(Builders.unkeyedListBuilder()
752 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
753 .withChild(Builders.unkeyedListEntryBuilder()
754 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
755 .withChild(Builders.choiceBuilder()
756 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
757 .withChild(Builders.unkeyedListBuilder()
758 .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_TYPE_NID)
759 .withChild(Builders.unkeyedListEntryBuilder()
760 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
761 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
762 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
763 AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
764 AbstractNumericOperandParser.GREATER_THAN_VALUE,
765 AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
766 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
767 .withValue(Uint8.valueOf(22)).build()).build())
768 .build()).build()).build()).build());
769 final FlowspecBuilder expectedFS = new FlowspecBuilder();
770 expectedFS.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(Lists.newArrayList(new TypesBuilder()
771 .setValue(Uint8.valueOf(22)).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
772 final List<Flowspec> expected = new ArrayList<>();
773 expected.add(expectedFS.build());
774 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
778 public void testExtractFlowspecSourceCodes() {
779 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
780 Builders.mapEntryBuilder();
781 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
782 entry.withChild(Builders.unkeyedListBuilder()
783 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
784 .withChild(Builders.unkeyedListEntryBuilder()
785 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
786 .withChild(Builders.choiceBuilder()
787 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
788 .withChild(Builders.unkeyedListBuilder()
789 .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_CODE_NID)
790 .withChild(Builders.unkeyedListEntryBuilder()
791 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
792 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
793 .withValue(Collections.emptySet()).build())
794 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
795 .withValue(Uint8.valueOf(23)).build()).build())
796 .build()).build()).build()).build());
797 final FlowspecBuilder expectedFS = new FlowspecBuilder();
798 expectedFS.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(Lists.newArrayList(new CodesBuilder()
799 .setValue(Uint8.valueOf(23)).setOp(new NumericOperand(false, false, false, false, false)).build()))
801 final List<Flowspec> expected = new ArrayList<>();
802 expected.add(expectedFS.build());
803 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
807 public void testExtractFlowspecSourceTcpFlags() {
808 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
809 Builders.mapEntryBuilder();
810 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
811 entry.withChild(Builders.unkeyedListBuilder()
812 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
813 .withChild(Builders.unkeyedListEntryBuilder()
814 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
815 .withChild(Builders.choiceBuilder()
816 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
817 .withChild(Builders.unkeyedListBuilder()
818 .withNodeIdentifier(AbstractFlowspecNlriParser.TCP_FLAGS_NID)
819 .withChild(Builders.unkeyedListEntryBuilder()
820 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
821 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
822 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
823 AbstractOperandParser.END_OF_LIST_VALUE)).build())
824 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
825 .withValue(Uint16.valueOf(99)).build()).build())
826 .build()).build()).build()).build());
827 final FlowspecBuilder expectedFS = new FlowspecBuilder();
828 expectedFS.setFlowspecType(new TcpFlagsCaseBuilder()
829 .setTcpFlags(Lists.newArrayList(new TcpFlagsBuilder()
830 .setValue(Uint16.valueOf(99))
831 .setOp(new BitmaskOperand(true, true, false, false))
834 final List<Flowspec> expected = new ArrayList<>();
835 expected.add(expectedFS.build());
836 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
840 public void testExtractFlowspecPacketLengths() {
841 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
842 Builders.mapEntryBuilder();
843 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
844 entry.withChild(Builders.unkeyedListBuilder()
845 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
846 .withChild(Builders.unkeyedListEntryBuilder()
847 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
848 .withChild(Builders.choiceBuilder()
849 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
850 .withChild(Builders.unkeyedListBuilder()
851 .withNodeIdentifier(AbstractFlowspecNlriParser.PACKET_LENGTHS_NID)
852 .withChild(Builders.unkeyedListEntryBuilder()
853 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
854 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
855 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
856 AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
857 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
858 .withValue(Uint16.valueOf(101)).build()).build())
859 .build()).build()).build()).build());
860 final FlowspecBuilder expectedFS = new FlowspecBuilder();
861 expectedFS.setFlowspecType(new PacketLengthCaseBuilder()
862 .setPacketLengths(Lists.newArrayList(new PacketLengthsBuilder()
863 .setValue(Uint16.valueOf(101))
864 .setOp(new NumericOperand(true, false, false, true, false))
867 final List<Flowspec> expected = new ArrayList<>();
868 expected.add(expectedFS.build());
869 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
873 public void testExtractFlowspecDscps() {
874 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
875 Builders.mapEntryBuilder();
876 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
877 entry.withChild(Builders.unkeyedListBuilder()
878 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
879 .withChild(Builders.unkeyedListEntryBuilder()
880 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
881 .withChild(Builders.choiceBuilder()
882 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
883 .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
884 .withChild(Builders.unkeyedListEntryBuilder()
885 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
886 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
887 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
888 AbstractOperandParser.END_OF_LIST_VALUE,
889 AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
890 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
891 .withValue(Uint8.valueOf(15)).build()).build())
892 .build()).build()).build()).build());
893 final FlowspecBuilder expectedFS = new FlowspecBuilder();
894 expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(Lists.newArrayList(new DscpsBuilder()
895 .setValue(new Dscp(Uint8.valueOf(15))).setOp(new NumericOperand(true, true, false, true, false)).build()))
897 final List<Flowspec> expected = new ArrayList<>();
898 expected.add(expectedFS.build());
899 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
903 public void testExtractFlowspecFragments() {
904 final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
905 Builders.mapEntryBuilder();
906 entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
907 entry.withChild(Builders.unkeyedListBuilder()
908 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
909 .withChild(Builders.unkeyedListEntryBuilder()
910 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
911 .withChild(Builders.choiceBuilder()
912 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
913 .withChild(Builders.unkeyedListBuilder()
914 .withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
915 .withChild(Builders.unkeyedListEntryBuilder()
916 .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
917 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
918 .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
919 AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE,
920 BitmaskOperandParser.NOT_VALUE)).build())
921 .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
922 .withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE,
923 AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE,
924 AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
925 .build()).build()).build()).build());
926 final FlowspecBuilder expectedFS = new FlowspecBuilder();
927 expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder()
928 .setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build()))
930 final List<Flowspec> expected = new ArrayList<>();
931 expected.add(expectedFS.build());
932 assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
936 public void testBatchedFlowspecNlri() throws Exception {
937 final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
938 flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
939 SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
941 final MpReachNlriBuilder result = new MpReachNlriBuilder();
942 result.setAfi(Ipv4AddressFamily.class);
943 result.setSafi(FlowspecSubsequentAddressFamily.class);
945 parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_BATCHED), result, null);
946 final MpReachNlri nlri = result.build();
948 final List<Flowspec> flowspecList = ((DestinationFlowspecCase) nlri.getAdvertizedRoutes().getDestinationType())
949 .getDestinationFlowspecIpv4().getFlowspec();
950 assertEquals(3, flowspecList.size());
951 assertEquals("216.58.245.101/32", ((DestinationPrefixCase) flowspecList.get(0).getFlowspecType())
952 .getDestinationPrefix().getValue());
953 assertEquals("216.58.218.196/32", ((DestinationPrefixCase) flowspecList.get(1).getFlowspecType())
954 .getDestinationPrefix().getValue());
955 assertEquals("216.58.216.195/32", ((DestinationPrefixCase) flowspecList.get(2).getFlowspecType())
956 .getDestinationPrefix().getValue());