Sonar minor warnings fix
[bgpcep.git] / bgp / flowspec / src / main / java / org / opendaylight / protocol / bgp / flowspec / FSIpv4NlriParser.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 com.google.common.annotations.VisibleForTesting;
11 import com.google.common.base.Optional;
12 import io.netty.buffer.ByteBuf;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Set;
16 import org.opendaylight.protocol.util.BitArray;
17 import org.opendaylight.protocol.util.Ipv4Util;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.Fragment;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.NumericOperand;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.FragmentCase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.flowspec.flowspec.type.DestinationPrefixCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.flowspec.flowspec.type.DestinationPrefixCaseBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.flowspec.flowspec.type.ProtocolIpCase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.flowspec.flowspec.type.ProtocolIpCaseBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.flowspec.flowspec.type.SourcePrefixCase;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.flowspec.flowspec.type.SourcePrefixCaseBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIps;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIpsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.flowspec._case.DestinationFlowspecBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
42 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
43 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
44 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
45 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
46 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
47 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
48
49 public final class FSIpv4NlriParser extends AbstractFSNlriParser {
50
51     private static final int IP_PROTOCOL_VALUE = 3;
52
53     @VisibleForTesting
54     static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
55
56     @Override
57     protected void serializeMpReachNlri(final Attributes1 pathAttributes, final ByteBuf byteAggregator) {
58         if (pathAttributes == null) {
59             return;
60         }
61         final AdvertizedRoutes routes = (pathAttributes.getMpReachNlri()).getAdvertizedRoutes();
62         if (routes != null && routes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) {
63             final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase flowspecCase = (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) routes.getDestinationType();
64             serializeNlri(flowspecCase.getDestinationFlowspec().getFlowspec(), byteAggregator);
65         }
66     }
67
68     @Override
69     protected void serializeMpUnreachNlri(final Attributes2 pathAttributes, final ByteBuf byteAggregator) {
70         if (pathAttributes == null) {
71             return;
72         }
73         final MpUnreachNlri mpUnreachNlri = pathAttributes.getMpUnreachNlri();
74         if (mpUnreachNlri.getWithdrawnRoutes() != null && mpUnreachNlri.getWithdrawnRoutes().getDestinationType() instanceof DestinationFlowspecCase) {
75             final DestinationFlowspecCase flowspecCase = (DestinationFlowspecCase) mpUnreachNlri.getWithdrawnRoutes().getDestinationType();
76             serializeNlri(flowspecCase.getDestinationFlowspec().getFlowspec(), byteAggregator);
77         }
78     }
79
80     @Override
81     protected void serializeSpecificFSType(final FlowspecType value, final ByteBuf nlriByteBuf) {
82         if (value instanceof DestinationPrefixCase) {
83             nlriByteBuf.writeByte(DESTINATION_PREFIX_VALUE);
84             nlriByteBuf.writeBytes(Ipv4Util.bytesForPrefixBegin(((DestinationPrefixCase) value).getDestinationPrefix()));
85         } else if (value instanceof SourcePrefixCase) {
86             nlriByteBuf.writeByte(SOURCE_PREFIX_VALUE);
87             nlriByteBuf.writeBytes(Ipv4Util.bytesForPrefixBegin(((SourcePrefixCase) value).getSourcePrefix()));
88         } else if (value instanceof ProtocolIpCase) {
89             nlriByteBuf.writeByte(IP_PROTOCOL_VALUE);
90             NumericOneByteOperandParser.INSTANCE.serialize(((ProtocolIpCase) value).getProtocolIps(), nlriByteBuf);
91         } else if (value instanceof FragmentCase) {
92             nlriByteBuf.writeByte(FRAGMENT_VALUE);
93             serializeFragments(((FragmentCase) value).getFragments(), nlriByteBuf);
94         }
95     }
96
97     @Override
98     DestinationType createWidthdrawnDestinationType(final List<Flowspec> dst) {
99         return new DestinationFlowspecCaseBuilder().setDestinationFlowspec(
100             new DestinationFlowspecBuilder().setFlowspec(
101                 dst).build()).build();
102     }
103
104     @Override
105     DestinationType createAdvertizedRoutesDestinationType(final List<Flowspec> dst) {
106         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
107             .setDestinationFlowspec(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.flowspec._case.DestinationFlowspecBuilder()
108                 .setFlowspec(dst).build()).build();
109     }
110
111     @Override
112     protected void setSpecificFlowspecType(final FlowspecBuilder builder, final short type, final ByteBuf nlri) {
113         switch (type) {
114         case DESTINATION_PREFIX_VALUE:
115             builder.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(Ipv4Util.prefixForByteBuf(nlri)).build());
116             break;
117         case SOURCE_PREFIX_VALUE:
118             builder.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(Ipv4Util.prefixForByteBuf(nlri)).build());
119             break;
120         case IP_PROTOCOL_VALUE:
121             builder.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(parseProtocolIp(nlri)).build());
122             break;
123         case FRAGMENT_VALUE:
124             builder.setFlowspecType(new FragmentCaseBuilder().setFragments(parseFragment(nlri)).build());
125             break;
126         default:
127             break;
128         }
129     }
130
131     private static List<ProtocolIps> parseProtocolIp(final ByteBuf nlri) {
132         final List<ProtocolIps> ips = new ArrayList<>();
133         boolean end = false;
134         // we can do this as all fields will be rewritten in the cycle
135         final ProtocolIpsBuilder builder = new ProtocolIpsBuilder();
136         while (!end) {
137             final byte b = nlri.readByte();
138             final NumericOperand op = NumericOneByteOperandParser.INSTANCE.parse(b);
139             builder.setOp(op);
140             builder.setValue(nlri.readUnsignedByte());
141             end = op.isEndOfList();
142             ips.add(builder.build());
143         }
144         return ips;
145     }
146
147     @Override
148     protected Fragment parseFragment(final byte fragment) {
149         final BitArray bs = BitArray.valueOf(fragment);
150         return new Fragment(bs.get(DONT_FRAGMENT), bs.get(FIRST_FRAGMENT), bs.get(IS_A_FRAGMENT), bs.get(LAST_FRAGMENT));
151     }
152
153     @Override
154     protected byte serializeFragment(final Fragment fragment) {
155         final BitArray bs = new BitArray(Byte.SIZE);
156         bs.set(DONT_FRAGMENT, fragment.isDoNot());
157         bs.set(FIRST_FRAGMENT, fragment.isFirst());
158         bs.set(IS_A_FRAGMENT, fragment.isIsA());
159         bs.set(LAST_FRAGMENT, fragment.isLast());
160         return bs.toByte();
161     }
162
163     @Override
164     public void extractSpecificFlowspec(final ChoiceNode fsType, final FlowspecBuilder fsBuilder) {
165         if (fsType.getChild(DEST_PREFIX_NID).isPresent()) {
166             fsBuilder.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(
167                 new Ipv4Prefix((String) fsType.getChild(DEST_PREFIX_NID).get().getValue())).build());
168         } else if (fsType.getChild(SOURCE_PREFIX_NID).isPresent()) {
169             fsBuilder.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix((String) fsType.getChild(SOURCE_PREFIX_NID).get().getValue()))
170                 .build());
171         } else if (fsType.getChild(PROTOCOL_IP_NID).isPresent()) {
172             fsBuilder.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(createProtocolsIps((UnkeyedListNode) fsType.getChild(PROTOCOL_IP_NID).get())).build());
173         }
174     }
175
176     private static List<ProtocolIps> createProtocolsIps(final UnkeyedListNode protocolIpsData) {
177         final List<ProtocolIps> protocolIps = new ArrayList<>();
178
179         for (final UnkeyedListEntryNode node : protocolIpsData.getValue()) {
180             final ProtocolIpsBuilder ipsBuilder = new ProtocolIpsBuilder();
181             final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
182             if (opValue.isPresent()) {
183                 ipsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set<String>) opValue.get().getValue()));
184             }
185             final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
186             if (valueNode.isPresent()) {
187                 ipsBuilder.setValue((Short) valueNode.get().getValue());
188             }
189             protocolIps.add(ipsBuilder.build());
190         }
191
192         return protocolIps;
193     }
194
195     @Override
196     protected void stringSpecificFSNlriType(final FlowspecType value, final StringBuilder buffer) {
197         if (value instanceof DestinationPrefixCase) {
198             buffer.append("to ");
199             buffer.append(((DestinationPrefixCase) value).getDestinationPrefix().getValue());
200         } else if (value instanceof SourcePrefixCase) {
201             buffer.append("from ");
202             buffer.append(((SourcePrefixCase) value).getSourcePrefix().getValue());
203         } else if (value instanceof ProtocolIpCase) {
204             buffer.append("where IP protocol ");
205             buffer.append(NumericOneByteOperandParser.INSTANCE.toString(((ProtocolIpCase) value).getProtocolIps()));
206         }
207     }
208
209 }