Provide Add Path support for all AFI/SAFI
[bgpcep.git] / bgp / flowspec / src / test / java / org / opendaylight / protocol / bgp / flowspec / SimpleFlowspecIpv4NlriParserTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.protocol.bgp.flowspec;
9
10 import static org.junit.Assert.assertArrayEquals;
11 import static org.junit.Assert.assertEquals;
12
13 import com.google.common.collect.Lists;
14 import com.google.common.collect.Sets;
15 import io.netty.buffer.ByteBuf;
16 import io.netty.buffer.Unpooled;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.Optional;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.mockito.Mock;
23 import org.mockito.Mockito;
24 import org.mockito.MockitoAnnotations;
25 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractNumericOperandParser;
26 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractOperandParser;
27 import org.opendaylight.protocol.bgp.flowspec.handlers.BitmaskOperandParser;
28 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
29 import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupport;
30 import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
31 import org.opendaylight.protocol.util.ByteArray;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.BitmaskOperand;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.Dscp;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.FlowspecSubsequentAddressFamily;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.Fragment;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.NumericOperand;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.Flowspec;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.FlowspecBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.FlowspecType;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.DestinationPortCaseBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.DscpCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.IcmpCodeCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.IcmpTypeCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PacketLengthCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PacketLengthCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PortCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.PortCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.SourcePortCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.TcpFlagsCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.TcpFlagsCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPorts;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPortsBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.dscp._case.Dscps;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.dscp._case.DscpsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.fragment._case.Fragments;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.fragment._case.FragmentsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.code._case.Codes;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.code._case.CodesBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.type._case.Types;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.icmp.type._case.TypesBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengths;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengthsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.port._case.Ports;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.port._case.PortsBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePorts;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePortsBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlags;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlagsBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCaseBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCaseBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCaseBuilder;
76 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;
77 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;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.destination.ipv4.DestinationFlowspecBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.flowspec.ipv4.route.FlowspecRoute;
80 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;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.PathId;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.AttributesBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes1;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes1Builder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes2;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes2Builder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpReachNlri;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpReachNlriBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpUnreachNlriBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
93 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
94 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
95 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
96 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
97 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
98
99 public class SimpleFlowspecIpv4NlriParserTest {
100
101     private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
102
103     static final PathId PATH_ID = new PathId(1L);
104     @Mock
105     private PeerSpecificParserConstraint constraint;
106     @Mock
107     private MultiPathSupport muliPathSupport;
108
109     private static final byte[] REACHED_NLRI = new byte[] {
110         0x21,   // NLRI length: 33
111         01, 0x20, 0x0a, 00, 01, 00,
112         02, 0x20, 01, 02, 03, 04,
113         03, (byte) 0x81, 06,
114         04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
115         05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
116         06, (byte) 0x91, 0x1f, (byte) 0x90
117     };
118
119     private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
120         0x0, 0x0, 0x0, 0x1,
121         0x21,   // NLRI length: 33
122         01, 0x20, 0x0a, 00, 01, 00,
123         02, 0x20, 01, 02, 03, 04,
124         03, (byte) 0x81, 06,
125         04, 03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
126         05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
127         06, (byte) 0x91, 0x1f, (byte) 0x90
128     };
129
130     private static final byte[] REACHED_NLRI_BATCHED = new byte[] {
131         0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xf5, 0x65,
132         0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xda, (byte) 0xc4,
133         0x06, 0x01, 0x20, (byte) 0xd8, 0x3a, (byte) 0xd8, (byte) 0xc3
134     };
135
136     private static final byte[] UNREACHED_NLRI = new byte[] {
137         0x1B,   // NLRI length: 27
138         07, 4, 2, (byte) 0x84, 3,
139         0x08, 4, 04, (byte) 0x80, 05,
140         0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
141         0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
142         0x0b, (byte) 0x82, 0x2a,
143         0x0c, (byte) 0x81, (byte) 0x0e
144     };
145
146     private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
147         0x0, 0x0, 0x0, 0x1,
148         0x1B,   // NLRI length: 27
149         07, 4, 2, (byte) 0x84, 3,
150         0x08, 4, 04, (byte) 0x80, 05,
151         0x09, 0x12, 04, 01, (byte) 0x91, 0x56, (byte) 0xb1,
152         0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
153         0x0b, (byte) 0x82, 0x2a,
154         0x0c, (byte) 0x81, (byte) 0x0e
155     };
156
157     private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
158     private final FlowspecActivator fsa = new FlowspecActivator(this.flowspecContext);
159     private final SimpleFlowspecIpv4NlriParser FS_PARSER = new SimpleFlowspecIpv4NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
160
161     @Before
162     public void setUp() {
163         MockitoAnnotations.initMocks(this);
164         Mockito.doReturn(Optional.of(this.muliPathSupport)).when(this.constraint).getPeerConstraint(Mockito.any());
165         Mockito.doReturn(true).when(this.muliPathSupport).isTableTypeSupported(Mockito.any());
166     }
167
168     @Test
169     public void testParseMpReachNlri() throws BGPParsingException {
170         final List<Flowspec> fs = new ArrayList<>();
171         final MpReachNlriBuilder mp = new MpReachNlriBuilder();
172
173         final FlowspecBuilder builder = new FlowspecBuilder();
174         final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(new Ipv4Prefix("10.0.1.0/32")).build();
175         builder.setFlowspecType(destinationPrefix);
176         fs.add(builder.build());
177         final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("1.2.3.4/32")).build();
178         builder.setFlowspecType(sourcePrefix);
179         fs.add(builder.build());
180
181         final FlowspecType prots = createProts();
182         builder.setFlowspecType(prots);
183         fs.add(builder.build());
184
185         final PortCase ps = createPorts();
186         builder.setFlowspecType(ps);
187         fs.add(builder.build());
188
189         final FlowspecType dps = createDps();
190         builder.setFlowspecType(dps);
191         fs.add(builder.build());
192
193         final FlowspecType sps = createSps();
194         builder.setFlowspecType(sps);
195         fs.add(builder.build());
196
197         mp.setAdvertizedRoutes(
198             new AdvertizedRoutesBuilder().setDestinationType(
199                 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
200                     .setDestinationFlowspec(
201                         new DestinationFlowspecBuilder()
202                             .setFlowspec(fs)
203                             .build()
204                     ).build()
205             ).build()
206         );
207
208         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
209
210         final MpReachNlriBuilder result = new MpReachNlriBuilder();
211         result.setAfi(Ipv4AddressFamily.class);
212         result.setSafi(FlowspecSubsequentAddressFamily.class);
213         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result);
214
215         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) result.getAdvertizedRoutes().getDestinationType())
216             .getDestinationFlowspec()
217             .getFlowspec();
218         testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
219
220         final ByteBuf buffer = Unpooled.buffer();
221         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(), buffer);
222         assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
223
224         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 is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ", this.FS_PARSER.stringNlri(flows));
225     }
226
227     private static void testFlows(final List<Flowspec> flows, final DestinationPrefixCase destinationPrefix,
228             final SourcePrefixCase sourcePrefix, final FlowspecType prots, final PortCase ps, final FlowspecType dps,
229             final FlowspecType sps) {
230         assertEquals(6, flows.size());
231         assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
232         assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
233         assertEquals(prots, flows.get(2).getFlowspecType());
234         assertEquals(ps, flows.get(3).getFlowspecType());
235         assertEquals(dps, flows.get(4).getFlowspecType());
236         assertEquals(sps, flows.get(5).getFlowspecType());
237     }
238
239     private static FlowspecType createSps() {
240         final List<SourcePorts> sports = Lists.newArrayList(new SourcePortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(8080).build());
241         return new SourcePortCaseBuilder().setSourcePorts(sports).build();
242     }
243
244     private static FlowspecType createProts() {
245         final List<ProtocolIps> protocols = Lists.newArrayList(new ProtocolIpsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
246         return new ProtocolIpCaseBuilder().setProtocolIps(protocols).build();
247     }
248
249     private static FlowspecType createDps() {
250         final List<DestinationPorts> destports = Lists.newArrayList(new DestinationPortsBuilder().setOp(new NumericOperand(false, false, false, true, false)).setValue(4089).build(),
251             new DestinationPortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(179).build());
252         return new DestinationPortCaseBuilder().setDestinationPorts(destports).build();
253     }
254
255     @Test
256     public void testParseMpReachNlriConstraint() throws BGPParsingException {
257         final List<Flowspec> fs = new ArrayList<>();
258         final MpReachNlriBuilder mp = new MpReachNlriBuilder();
259
260         final FlowspecBuilder builder = new FlowspecBuilder();
261         final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(new Ipv4Prefix("10.0.1.0/32")).build();
262         builder.setFlowspecType(destinationPrefix);
263         fs.add(builder.build());
264         final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("1.2.3.4/32")).build();
265         builder.setFlowspecType(sourcePrefix);
266         fs.add(builder.build());
267
268         final FlowspecType prots = createProts();
269         builder.setFlowspecType(prots);
270         fs.add(builder.build());
271
272         final PortCase ps = createPorts();
273         builder.setFlowspecType(ps);
274         fs.add(builder.build());
275
276         final FlowspecType dps = createDps();
277         builder.setFlowspecType(dps);
278         fs.add(builder.build());
279
280         final FlowspecType sps = createSps();
281         builder.setFlowspecType(sps);
282         fs.add(builder.build());
283
284         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
285             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
286                 .setDestinationFlowspec(
287                     new DestinationFlowspecBuilder()
288                         .setPathId(PATH_ID)
289                         .setFlowspec(fs)
290                         .build()
291                 ).build()
292             ).build()
293         );
294
295         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
296
297         final MpReachNlriBuilder result = new MpReachNlriBuilder();
298         result.setAfi(Ipv4AddressFamily.class);
299         result.setSafi(FlowspecSubsequentAddressFamily.class);
300         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
301
302         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) result.getAdvertizedRoutes().getDestinationType())
303             .getDestinationFlowspec()
304             .getFlowspec();
305         testFlows(flows, destinationPrefix, sourcePrefix, prots, ps, dps, sps);
306
307         final ByteBuf buffer = Unpooled.buffer();
308         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(), buffer);
309         assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
310
311         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 is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ", this.FS_PARSER.stringNlri(flows));
312     }
313
314     private static PortCase createPorts() {
315         final List<Ports> ports = Lists.newArrayList(new PortsBuilder().setOp(new NumericOperand(false, false, true, true, false)).setValue(137).build(),
316             new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(139).build(),
317             new PortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(8080).build());
318
319         return new PortCaseBuilder().setPorts(ports).build();
320     }
321
322     @Test
323     public void testParseMpUnreachNlri() throws BGPParsingException {
324         final List<Flowspec> fs = new ArrayList<>();
325         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
326
327         final FlowspecBuilder builder = new FlowspecBuilder();
328
329         final FlowspecType icmpType = createIcmpType();
330         builder.setFlowspecType(icmpType);
331         fs.add(builder.build());
332
333         final FlowspecType icmpCode = createIcmpCode();
334         builder.setFlowspecType(icmpCode);
335         fs.add(builder.build());
336
337         final TcpFlagsCase tcp = createTcp();
338         builder.setFlowspecType(tcp);
339         fs.add(builder.build());
340
341         final PacketLengthCase packet = createPackets();
342         builder.setFlowspecType(packet);
343         fs.add(builder.build());
344
345         final FlowspecType dscp = createDscp();
346         builder.setFlowspecType(dscp);
347         fs.add(builder.build());
348
349         final FlowspecType fragment = createFragment();
350         builder.setFlowspecType(fragment);
351         fs.add(builder.build());
352
353         mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
354             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
355                 .setDestinationFlowspec(
356                     new DestinationFlowspecBuilder()
357                         .setFlowspec(fs)
358                         .build()
359                 ).build()
360             ).build()
361         );
362
363         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
364
365         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
366         result.setAfi(Ipv4AddressFamily.class);
367         result.setSafi(FlowspecSubsequentAddressFamily.class);
368         parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result);
369
370         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase) result.getWithdrawnRoutes().getDestinationType())
371             .getDestinationFlowspec()
372             .getFlowspec();
373         checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
374
375         final ByteBuf buffer = Unpooled.buffer();
376         parser.serializeNlri(new Object[] {flows}, null, buffer);
377         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
378
379         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
380         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
381
382         assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ", this.FS_PARSER.stringNlri(flows));
383
384     }
385
386     private static FlowspecType createFragment() {
387         final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(new Fragment(false, true, true, true)).build());
388         return new FragmentCaseBuilder().setFragments(fragments).build();
389     }
390
391     private static FlowspecType createDscp() {
392         final List<Dscps> dscps = Lists.newArrayList(new DscpsBuilder().setOp(new NumericOperand(false, true, false, true, false)).setValue(new Dscp((short) 42)).build());
393         return new DscpCaseBuilder().setDscps(dscps).build();
394     }
395
396     private static PacketLengthCase createPackets() {
397         final List<PacketLengths> packets = Lists.newArrayList(new PacketLengthsBuilder().setOp(new NumericOperand(false, true, false, false, true))
398             .setValue(57005).build());
399         return new PacketLengthCaseBuilder().setPacketLengths(packets).build();
400     }
401
402     private static TcpFlagsCase createTcp() {
403         final List<TcpFlags> flags = Lists.newArrayList(new TcpFlagsBuilder().setOp(new BitmaskOperand(false, false, false, true)).setValue(1025).build(),
404             new TcpFlagsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(22193).build());
405         return new TcpFlagsCaseBuilder().setTcpFlags(flags).build();
406     }
407
408     private static FlowspecType createIcmpCode() {
409         final List<Codes> codes = Lists.newArrayList(new CodesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue((short) 4).build(),
410             new CodesBuilder().setOp(new NumericOperand(false, true, false, false, false)).setValue((short) 5).build());
411         return new IcmpCodeCaseBuilder().setCodes(codes).build();
412     }
413
414     private static FlowspecType createIcmpType() {
415         final List<Types> types = Lists.newArrayList(new TypesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue((short) 2).build(),
416             new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue((short) 3).build());
417         return new IcmpTypeCaseBuilder().setTypes(types).build();
418     }
419
420     private static void checkUnreachFlows(final List<Flowspec> flows, final FlowspecType icmpType,
421             final FlowspecType icmpCode, final TcpFlagsCase tcp, final PacketLengthCase packet,
422             final FlowspecType dscp, final FlowspecType fragment) {
423         assertEquals(6, flows.size());
424         assertEquals(icmpType, flows.get(0).getFlowspecType());
425         assertEquals(icmpCode, flows.get(1).getFlowspecType());
426         assertEquals(tcp, flows.get(2).getFlowspecType());
427         assertEquals(packet, flows.get(3).getFlowspecType());
428         assertEquals(dscp, flows.get(4).getFlowspecType());
429         assertEquals(fragment, flows.get(5).getFlowspecType());
430     }
431
432     @Test
433     public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
434         final List<Flowspec> fs = new ArrayList<>();
435         final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
436
437         final FlowspecBuilder builder = new FlowspecBuilder();
438
439         final FlowspecType icmpType = createIcmpType();
440         builder.setFlowspecType(icmpType);
441         fs.add(builder.build());
442
443         final FlowspecType icmpCode = createIcmpCode();
444         builder.setFlowspecType(icmpCode);
445         fs.add(builder.build());
446
447         final TcpFlagsCase tcp = createTcp();
448         builder.setFlowspecType(tcp);
449         fs.add(builder.build());
450
451         final PacketLengthCase packet = createPackets();
452         builder.setFlowspecType(packet);
453         fs.add(builder.build());
454
455         final FlowspecType dscp = createDscp();
456         builder.setFlowspecType(dscp);
457         fs.add(builder.build());
458
459         final FlowspecType fragment = createFragment();
460         builder.setFlowspecType(fragment);
461         fs.add(builder.build());
462
463         mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
464             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
465                 .setDestinationFlowspec(
466                     new DestinationFlowspecBuilder()
467                         .setPathId(PATH_ID)
468                         .setFlowspec(fs)
469                         .build()
470                 ).build()
471             ).build()
472         );
473
474         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
475
476         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
477         result.setAfi(Ipv4AddressFamily.class);
478         result.setSafi(FlowspecSubsequentAddressFamily.class);
479         parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
480
481         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase) result.getWithdrawnRoutes().getDestinationType())
482             .getDestinationFlowspec()
483             .getFlowspec();
484         checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
485
486
487         final ByteBuf buffer = Unpooled.buffer();
488         parser.serializeNlri(new Object[] {flows}, PATH_ID, buffer);
489         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
490
491         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
492         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
493
494         assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ", this.FS_PARSER.stringNlri(flows));
495
496     }
497
498     @Test
499     public void testExtractFlowspecDestPrefix() {
500         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
501         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
502         entry.withChild(Builders.unkeyedListBuilder()
503             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
504             .withChild(Builders.unkeyedListEntryBuilder()
505                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
506                 .withChild(Builders.choiceBuilder()
507                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
508                     .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID).withValue("127.0.0.5/32").build()).build()).build()).build());
509
510         final FlowspecBuilder expectedFS = new FlowspecBuilder();
511         expectedFS.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(new Ipv4Prefix("127.0.0.5/32")).build());
512         final List<Flowspec> expected = new ArrayList<>();
513         expected.add(expectedFS.build());
514         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
515     }
516
517     @Test
518     public void testExtractFlowspecSourcePrefix() {
519         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
520         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
521         entry.withChild(Builders.unkeyedListBuilder()
522             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
523             .withChild(Builders.unkeyedListEntryBuilder()
524                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
525                 .withChild(Builders.choiceBuilder()
526                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
527                     .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID).withValue("127.0.0.6/32").build()).build()).build()).build());
528
529         final FlowspecBuilder expectedFS = new FlowspecBuilder();
530         expectedFS.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32")).build());
531         final List<Flowspec> expected = new ArrayList<>();
532         expected.add(expectedFS.build());
533         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
534     }
535
536     @Test
537     public void testExtractFlowspecProtocolIps() {
538         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
539         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
540         entry.withChild(Builders.unkeyedListBuilder()
541             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
542             .withChild(Builders.unkeyedListEntryBuilder()
543                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
544                 .withChild(Builders.choiceBuilder()
545                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
546                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
547                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
548                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
549                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 100).build()).build())
550                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
551                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
552                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 200).build()).build())
553                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
554                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
555                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 240).build()).build())
556                         .build()).build()).build()).build());
557
558         final FlowspecBuilder expectedFS = new FlowspecBuilder();
559         expectedFS.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(Lists.newArrayList(
560             new ProtocolIpsBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false)).build(),
561             new ProtocolIpsBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false)).build(),
562             new ProtocolIpsBuilder().setValue((short) 240).setOp(new NumericOperand(true, true, true, false, false)).build())).build());
563         final List<Flowspec> expected = new ArrayList<>();
564         expected.add(expectedFS.build());
565         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
566     }
567
568     @Test
569     public void testExtractFlowspecPorts() {
570         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
571         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
572         entry.withChild(Builders.unkeyedListBuilder()
573             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
574             .withChild(Builders.unkeyedListEntryBuilder()
575                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
576                 .withChild(Builders.choiceBuilder()
577                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
578                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
579                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
580                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
581                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(100).build()).build())
582                         .build()).build()).build()).build());
583
584         final FlowspecBuilder expectedFS = new FlowspecBuilder();
585         expectedFS.setFlowspecType(new PortCaseBuilder().setPorts(Lists.newArrayList(new PortsBuilder().setValue(100).setOp(new NumericOperand(true, true, false, false, true)).build())).build());
586         final List<Flowspec> expected = new ArrayList<>();
587         expected.add(expectedFS.build());
588         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
589     }
590
591     @Test
592     public void testExtractFlowspecDestinationPorts() {
593         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
594         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
595         entry.withChild(Builders.unkeyedListBuilder()
596             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
597             .withChild(Builders.unkeyedListEntryBuilder()
598                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
599                 .withChild(Builders.choiceBuilder()
600                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
601                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PORT_NID)
602                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
603                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
604                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(1024).build()).build())
605                         .build()).build()).build()).build());
606         final FlowspecBuilder expectedFS = new FlowspecBuilder();
607         expectedFS.setFlowspecType(new DestinationPortCaseBuilder().setDestinationPorts(Lists.newArrayList(new DestinationPortsBuilder().setValue(1024).setOp(new NumericOperand(false, true, true, false, false)).build())).build());
608         final List<Flowspec> expected = new ArrayList<>();
609         expected.add(expectedFS.build());
610         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
611     }
612
613     @Test
614     public void testExtractFlowspecSourcePorts() {
615         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
616         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
617         entry.withChild(Builders.unkeyedListBuilder()
618             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
619             .withChild(Builders.unkeyedListEntryBuilder()
620                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
621                 .withChild(Builders.choiceBuilder()
622                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
623                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PORT_NID)
624                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
625                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
626                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(8080).build()).build())
627                         .build()).build()).build()).build());
628         final FlowspecBuilder expectedFS = new FlowspecBuilder();
629         expectedFS.setFlowspecType(new SourcePortCaseBuilder().setSourcePorts(Lists.newArrayList(new SourcePortsBuilder().setValue(8080).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
630         final List<Flowspec> expected = new ArrayList<>();
631         expected.add(expectedFS.build());
632         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
633     }
634
635     @Test
636     public void testExtractFlowspecSourceTypes() {
637         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
638         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(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.ICMP_TYPE_NID)
646                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
647                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
648                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 22).build()).build())
649                         .build()).build()).build()).build());
650         final FlowspecBuilder expectedFS = new FlowspecBuilder();
651         expectedFS.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(Lists.newArrayList(new TypesBuilder().setValue((short) 22).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
652         final List<Flowspec> expected = new ArrayList<>();
653         expected.add(expectedFS.build());
654         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
655     }
656
657     @Test
658     public void testExtractFlowspecSourceCodes() {
659         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
660         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
661         entry.withChild(Builders.unkeyedListBuilder()
662             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
663             .withChild(Builders.unkeyedListEntryBuilder()
664                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
665                 .withChild(Builders.choiceBuilder()
666                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
667                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_CODE_NID)
668                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
669                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet()).build())
670                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 23).build()).build())
671                         .build()).build()).build()).build());
672         final FlowspecBuilder expectedFS = new FlowspecBuilder();
673         expectedFS.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(Lists.newArrayList(new CodesBuilder().setValue((short) 23).setOp(new NumericOperand(false, false, false, false, false)).build())).build());
674         final List<Flowspec> expected = new ArrayList<>();
675         expected.add(expectedFS.build());
676         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
677     }
678
679     @Test
680     public void testExtractFlowspecSourceTcpFlags() {
681         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
682         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(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().withNodeIdentifier(AbstractFlowspecNlriParser.TCP_FLAGS_NID)
690                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
691                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE)).build())
692                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(99).build()).build())
693                         .build()).build()).build()).build());
694         final FlowspecBuilder expectedFS = new FlowspecBuilder();
695         expectedFS.setFlowspecType(new TcpFlagsCaseBuilder().setTcpFlags(Lists.newArrayList(new TcpFlagsBuilder().setValue(99).setOp(new BitmaskOperand(true, true, false, false)).build())).build());
696         final List<Flowspec> expected = new ArrayList<>();
697         expected.add(expectedFS.build());
698         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
699     }
700
701     @Test
702     public void testExtractFlowspecPacketLengths() {
703         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
704         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
705         entry.withChild(Builders.unkeyedListBuilder()
706             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
707             .withChild(Builders.unkeyedListEntryBuilder()
708                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
709                 .withChild(Builders.choiceBuilder()
710                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
711                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PACKET_LENGTHS_NID)
712                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
713                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
714                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(101).build()).build())
715                         .build()).build()).build()).build());
716         final FlowspecBuilder expectedFS = new FlowspecBuilder();
717         expectedFS.setFlowspecType(new PacketLengthCaseBuilder().setPacketLengths(Lists.newArrayList(new PacketLengthsBuilder().setValue(101).setOp(new NumericOperand(true, false, false, true, false)).build())).build());
718         final List<Flowspec> expected = new ArrayList<>();
719         expected.add(expectedFS.build());
720         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
721     }
722
723     @Test
724     public void testExtractFlowspecDscps() {
725         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
726         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
727         entry.withChild(Builders.unkeyedListBuilder()
728             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
729             .withChild(Builders.unkeyedListEntryBuilder()
730                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
731                 .withChild(Builders.choiceBuilder()
732                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
733                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
734                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
735                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
736                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 15).build()).build())
737                         .build()).build()).build()).build());
738         final FlowspecBuilder expectedFS = new FlowspecBuilder();
739         expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(Lists.newArrayList(new DscpsBuilder().setValue(new Dscp((short) 15)).setOp(new NumericOperand(true, true, false, true, false)).build())).build());
740         final List<Flowspec> expected = new ArrayList<>();
741         expected.add(expectedFS.build());
742         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
743     }
744
745     @Test
746     public void testExtractFlowspecFragments() {
747         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
748         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
749         entry.withChild(Builders.unkeyedListBuilder()
750             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
751             .withChild(Builders.unkeyedListEntryBuilder()
752                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
753                 .withChild(Builders.choiceBuilder()
754                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
755                     .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
756                         .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
757                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)).build())
758                             .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE, AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE, AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
759                         .build()).build()).build()).build());
760         final FlowspecBuilder expectedFS = new FlowspecBuilder();
761         expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build());
762         final List<Flowspec> expected = new ArrayList<>();
763         expected.add(expectedFS.build());
764         assertEquals(expected, this.FS_PARSER.extractFlowspec(entry.build()));
765     }
766
767     @Test
768     public void testBatchedFlowspecNlri() throws Exception {
769         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
770
771         final MpReachNlriBuilder result = new MpReachNlriBuilder();
772         result.setAfi(Ipv4AddressFamily.class);
773         result.setSafi(FlowspecSubsequentAddressFamily.class);
774
775         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_BATCHED), result);
776         final MpReachNlri nlri = result.build();
777
778         final List<Flowspec> flowspecList = ((DestinationFlowspecCase) nlri.getAdvertizedRoutes().getDestinationType())
779                 .getDestinationFlowspec().getFlowspec();
780         assertEquals(3, flowspecList.size());
781         assertEquals("216.58.245.101/32", ((DestinationPrefixCase) flowspecList.get(0).getFlowspecType()).getDestinationPrefix().getValue());
782         assertEquals("216.58.218.196/32", ((DestinationPrefixCase) flowspecList.get(1).getFlowspecType()).getDestinationPrefix().getValue());
783         assertEquals("216.58.216.195/32", ((DestinationPrefixCase) flowspecList.get(2).getFlowspecType()).getDestinationPrefix().getValue());
784     }
785
786 }
787