BUG-4692: Migrate TCP-MD5 support in bgp package to netty's native-epoll
[bgpcep.git] / bgp / linkstate / src / main / java / org / opendaylight / protocol / bgp / linkstate / nlri / PrefixIpv4NlriParser.java
1 /*
2  * Copyright (c) 2014 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.linkstate.nlri;
9
10 import com.google.common.annotations.VisibleForTesting;
11 import io.netty.buffer.ByteBuf;
12 import io.netty.buffer.ByteBufUtil;
13 import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil;
14 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
15 import org.opendaylight.protocol.util.Ipv4Util;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NlriType;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.OspfRouteType;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.TopologyIdentifier;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.ObjectType;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCase;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCaseBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.AdvertisingNodeDescriptors;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.PrefixDescriptors;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.PrefixDescriptorsBuilder;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 @VisibleForTesting
32 public final class PrefixIpv4NlriParser implements NlriTypeCaseParser  {
33
34     private static final Logger LOG = LoggerFactory.getLogger(PrefixIpv4NlriParser.class);
35
36     /* Prefix Descriptor TLVs */
37     private static final int OSPF_ROUTE_TYPE = 264;
38     private static final int IP_REACHABILITY = 265;
39
40     /* Prefix Descriptor QNames */
41     @VisibleForTesting
42     public static final NodeIdentifier OSPF_ROUTE_NID = new NodeIdentifier(QName.create(PrefixDescriptors.QNAME, "ospf-route-type").intern());
43     @VisibleForTesting
44     public static final NodeIdentifier IP_REACH_NID = new NodeIdentifier(QName.create(PrefixDescriptors.QNAME, "ip-reachability-information").intern());
45
46     static PrefixDescriptors parseIpv4PrefixDescriptors(final ByteBuf buffer) throws BGPParsingException {
47         final PrefixDescriptorsBuilder builder = new PrefixDescriptorsBuilder();
48         while (buffer.isReadable()) {
49             final int type = buffer.readUnsignedShort();
50             final int length = buffer.readUnsignedShort();
51             final ByteBuf value = buffer.readSlice(length);
52             if (LOG.isTraceEnabled()) {
53                 LOG.trace("Parsing Prefix Descriptor: {}", ByteBufUtil.hexDump(value));
54             }
55             switch (type) {
56             case TlvUtil.MULTI_TOPOLOGY_ID:
57                 final TopologyIdentifier topologyId = new TopologyIdentifier(value.readShort() & TlvUtil.TOPOLOGY_ID_OFFSET);
58                 builder.setMultiTopologyId(topologyId);
59                 LOG.trace("Parsed Topology Identifier: {}", topologyId);
60                 break;
61             case OSPF_ROUTE_TYPE:
62                 final int rt = value.readByte();
63                 final OspfRouteType routeType = OspfRouteType.forValue(rt);
64                 if (routeType == null) {
65                     throw new BGPParsingException("Unknown OSPF Route Type: " + rt);
66                 }
67                 builder.setOspfRouteType(routeType);
68                 LOG.trace("Parser RouteType: {}", routeType);
69                 break;
70             case IP_REACHABILITY:
71                 final IpPrefix prefix = new IpPrefix(Ipv4Util.prefixForByteBuf(value));
72                 builder.setIpReachabilityInformation(prefix);
73                 LOG.trace("Parsed IP reachability info: {}", prefix);
74                 break;
75             default:
76                 throw new BGPParsingException("Prefix Descriptor not recognized, type: " + type);
77             }
78         }
79         LOG.debug("Finished parsing Ipv4 Prefix descriptors.");
80         return builder.build();
81     }
82
83     @Override
84     public ObjectType parseTypeNlri(final ByteBuf nlri, final NlriType type, final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NodeIdentifier localdescriptor, final ByteBuf restNlri) throws BGPParsingException {
85         PrefixCaseBuilder prefixbuilder = new PrefixCaseBuilder();
86         PrefixDescriptors prefdesc = parseIpv4PrefixDescriptors(restNlri);
87         PrefixCase prefixcase = prefixbuilder.setAdvertisingNodeDescriptors((AdvertisingNodeDescriptors) localdescriptor).setPrefixDescriptors(prefdesc).build();
88         return prefixcase;
89     }
90
91 }