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  */
9 
10 #ifndef _OPENBMP_MPLINKSTATE_H_
11 #define _OPENBMP_MPLINKSTATE_H_
12 
13 #include <cstdint>
14 #include <cinttypes>
15 #include <sys/types.h>
16 
17 #include "MPReachAttr.h"
18 #include "MPUnReachAttr.h"
19 #include "Logger.h"
20 #include "MsgBusInterface.hpp"
21 
22 namespace bgp_msg {
23 
24     class MPLinkState {
25 
26     public:
27         /**
28          * Defines the BGP link state NLRI types
29          *      https://tools.ietf.org/html/draft-ietf-idr-ls-distribution-10#section-3.2
30          */
31         enum NLRI_TYPES {
32             NLRI_TYPE_NODE = 1,                        ///< Node
33             NLRI_TYPE_LINK,                             ///< Link
34             NLRI_TYPE_IPV4_PREFIX,                      ///< IPv4 Prefix
35             NLRI_TYPE_IPV6_PREFIX                       ///< IPv6 Prefix
36         };
37 
38         /**
39          * Defines the NLRI protocol-id values
40          */
41         enum NLRI_PROTOCOL_IDS {
42             NLRI_PROTO_ISIS_L1 = 1,                    ///< IS-IS Level 1
43             NLRI_PROTO_ISIS_L2,                        ///< IS-IS Level 2
44             NLRI_PROTO_OSPFV2,                         ///< OSPFv2
45             NLRI_PROTO_DIRECT,                         ///< Direct
46             NLRI_PROTO_STATIC,                         ///< Static configuration
47             NLRI_PROTO_OSPFV3,                         ///< OSPFv3
48             NLRI_PROTO_EPE=7                           ///< EPE per draft-ietf-idr-bgpls-segment-routing-epe
49         };
50 
51         /**
52          * Node (local and remote) common fields
53          */
54         struct node_descriptor {
55             uint32_t    asn;                           ///< BGP ASN
56             uint32_t    bgp_ls_id;                     ///< BGP-LS Identifier
57             uint8_t     igp_router_id[8];              ///< IGP router ID
58             uint8_t     ospf_area_Id[4];               ///< OSPF area ID
59             uint32_t    bgp_router_id;                 ///< BGP router ID (draft-ietf-idr-bgpls-segment-routing-epe)
60             uint8_t     hash_bin[16];                  ///< binary hash for node descriptor
61         };
62 
63         /**
64          * Node descriptor Sub-TLV's
65          *      Used by both remote and local node descriptors
66          */
67         enum NODE_DESCR_SUB_TYPES {
68             NODE_DESCR_LOCAL_DESCR              = 256,      ///< Local node descriptor
69             NODE_DESCR_REMOTE_DESCR,                        ///< Remote node descriptor
70 
71             NODE_DESCR_AS                       = 512,      ///< Autonomous System (len=4)
72             NODE_DESCR_BGP_LS_ID,                           ///< BGP-LS Identifier (len=4)
73             NODE_DESCR_OSPF_AREA_ID,                        ///< OSPF Area-ID (len=4)
74             NODE_DESCR_IGP_ROUTER_ID,                       ///< IGP Router-ID (len=variable)
75             NODE_DESCR_BGP_ROUTER_ID                        ///< BGP Router ID (draft-ietf-idr-bgpls-segment-routing-epe)
76         };
77 
78 
79         /**
80          * Node (local and remote) common fields
81          */
82         struct link_descriptor {
83             uint32_t    local_id;                           ///< Link Local ID
84             uint32_t    remote_id;                          ///< Link Remote ID
85             uint8_t     intf_addr[16];                      ///< Interface binary address
86             uint8_t     nei_addr[16];                       ///< Neighbor binary address
87             uint32_t    mt_id;                              ///< Multi-Topology ID
88             bool        isIPv4;                             ///< True if IPv4, false if IPv6
89         };
90 
91         /**
92          * Link Descriptor Sub-TLV's
93          */
94         enum LINK_DESCR_SUB_TYPES {
95             LINK_DESCR_ID                       = 258,      ///< Link Local/Remote Identifiers 22/4 (rfc5307/1.1)
96             LINK_DESCR_IPV4_INTF_ADDR,                      ///< IPv4 interface address 22/6 (rfc5305/3.2)
97             LINK_DESCR_IPV4_NEI_ADDR,                       ///< IPv4 neighbor address 22/8 (rfc5305/3.3)
98             LINK_DESCR_IPV6_INTF_ADDR,                      ///< IPv6 interface address 22/12 (rfc6119/4.2)
99             LINK_DESCR_IPV6_NEI_ADDR,                       ///< IPv6 neighbor address 22/13 (rfc6119/4.3)
100             LINK_DESCR_MT_ID                                ///< Multi-Topology Identifier
101         };
102 
103 
104         /**
105          * Node (local and remote) common fields
106          */
107         struct prefix_descriptor {
108             char        ospf_route_type[32];                ///< OSPF Route type in string form for DB enum
109             uint32_t    mt_id;                              ///< Multi-Topology ID
110             uint8_t     prefix[16];                         ///< Prefix binary address
111             uint8_t     prefix_bcast[16];                   ///< Prefix broadcast/ending binary address
112             uint8_t     prefix_len;                         ///< Length of prefix in bits
113         };
114 
115         /**
116          * Prefix Descriptor Sub-TLV's
117          */
118         enum PREFIX_DESCR_SUB_YPTES {
119             PREFIX_DESCR_MT_ID                  = 263,      ///< Multi-Topology Identifier (len=variable)
120             PREFIX_DESCR_OSPF_ROUTE_TYPE,                   ///< OSPF Route Type (len=1)
121             PREFIX_DESCR_IP_REACH_INFO                      ///< IP Reachability Information (len=variable)
122         };
123 
124         /**
125          * OSPF Route Types
126          */
127         enum OSPF_ROUTE_TYPES {
128             OSPF_RT_INTRA_AREA                  = 1,        ///< Intra-Area
129             OSPF_RT_INTER_AREA,                             ///< Inter-Area
130             OSPF_RT_EXTERNAL_1,                             ///< External type 1
131             OSPF_RT_EXTERNAL_2,                             ///< External type 2
132             OSPF_RT_NSSA_1,                                 ///< NSSA type 1
133             OSPF_RT_NSSA_2                                  ///< NSSA type 2
134         };
135 
136 
137         /**
138          * Constructor for class
139          *
140          * \details Handles bgp Extended Communities
141          *
142          * \param [in]     logPtr       Pointer to existing Logger for app logging
143          * \param [in]     peerAddr     Printed form of peer address used for logging
144          * \param [out]    parsed_data  Reference to parsed_update_data; will be updated with all parsed data
145          * \param [in]     enable_debug Debug true to enable, false to disable
146          */
147         MPLinkState(Logger *logPtr, std::string peerAddr,
148                     UpdateMsg::parsed_update_data *parsed_data, bool enable_debug);
149         virtual ~MPLinkState();
150 
151         /**
152          * MP Reach Link State NLRI parse
153          *
154          * \details Will handle parsing the link state NLRI
155          *
156          * \param [in]   nlri           Reference to parsed NLRI struct
157          */
158         void parseReachLinkState(MPReachAttr::mp_reach_nlri &nlri);
159 
160         /**
161          * MP UnReach Link State NLRI parse
162          *
163          * \details Will handle parsing the unreach link state NLRI
164          *
165          * \param [in]   nlri           Reference to parsed NLRI struct
166          */
167         void parseUnReachLinkState(MPUnReachAttr::mp_unreach_nlri &nlri);
168 
169 
170     private:
171         bool             debug;                           ///< debug flag to indicate debugging
172         Logger           *logger;                         ///< Logging class pointer
173         std::string      peer_addr;                       ///< Printed form of the peer address for logging
174 
175         UpdateMsg::parsed_update_data *parsed_data;       ///< Parsed data structure
176         UpdateMsg::parsed_data_ls     *ls_data;           ///< Parsed LS Data
177 
178         /**********************************************************************************//*
179          * Parses Link State NLRI data
180          *
181          * \details Will parse the link state NLRI's from MP_REACH or MP_UNREACH.
182          *
183          * \param [in]   data           Pointer to the NLRI data
184          * \param [in]   len            Length of the NLRI data
185          */
186         void parseLinkStateNlriData(u_char *data, uint16_t len);
187 
188         /**********************************************************************************//*
189          * Parse NODE NLRI
190          *
191          * \details will parse the node NLRI type. Data starts at local node descriptor.
192          *
193          * \param [in]   data           Pointer to the start of the node NLRI data
194          * \param [in]   data_len       Length of the data
195          * \param [in]   id             NLRI/type identifier
196          * \param [in]   proto_id       NLRI protocol type id
197          */
198         void parseNlriNode(u_char *data, int data_len, uint64_t id, uint8_t proto_id);
199 
200         /**********************************************************************************//*
201          * Parse LINK NLRI
202          *
203          * \details will parse the LINK NLRI type. Data starts at local node descriptor.
204          *
205          * \param [in]   data           Pointer to the start of the node NLRI data
206          * \param [in]   data_len       Length of the data
207          * \param [in]   id             NLRI/type identifier
208          * \param [in]   proto_id       NLRI protocol type id
209          */
210         void parseNlriLink(u_char *data, int data_len, uint64_t id, uint8_t proto_id);
211 
212         /**********************************************************************************//*
213          * Parse PREFIX NLRI
214          *
215          * \details will parse the PREFIX NLRI type.  Data starts at local node descriptor.
216          *
217          * \param [in]   data           Pointer to the start of the node NLRI data
218          * \param [in]   data_len       Length of the data
219          * \param [in]   id             NLRI/type identifier
220          * \param [in]   proto_id       NLRI protocol type id
221          * \param [in]   isIPv4         Bool value to indicate IPv4(true) or IPv6(false)
222          */
223         void parseNlriPrefix(u_char *data, int data_len, uint64_t id, uint8_t proto_id, bool isIPv4);
224 
225         /**********************************************************************************//*
226          * Parse Node Descriptor
227          *
228          * \details will parse node descriptor
229          *
230          * \param [in]   data           Pointer to the start of the node NLRI data
231          * \param [in]   data_len       Length of the data
232          * \param [out]  info           Node descriptor information returned/updated
233          *
234          * \returns number of bytes read
235          */
236         int parseDescrLocalRemoteNode(u_char *data, int data_len, node_descriptor &info);
237 
238         /**********************************************************************************//*
239          * Parse Link Descriptor sub-tlvs
240          *
241          * \details will parse a link descriptor (series of sub-tlv's)
242          *
243          * \param [in]   data           Pointer to the start of the node NLRI data
244          * \param [in]   data_len       Length of the data
245          * \param [out]  info           link descriptor information returned/updated
246          *
247          * \returns number of bytes read
248          */
249         int parseDescrLink(u_char *data, int data_len, link_descriptor &info);
250 
251         /**********************************************************************************//*
252          * Parse Prefix Descriptor sub-tlvs
253          *
254          * \details will parse a prefix descriptor (series of sub-tlv's)
255          *
256          * \param [in]   data           Pointer to the start of the node NLRI data
257          * \param [in]   data_len       Length of the data
258          * \param [out]  info           prefix descriptor information returned/updated
259          * \param [in]   isIPv4         Bool value to indicate IPv4(true) or IPv6(false)
260          *
261          * \returns number of bytes read
262          */
263         int parseDescrPrefix(u_char *data, int data_len, prefix_descriptor &info, bool isIPv4);
264 
265         /**********************************************************************************//*
266          * Decode Protocol ID
267          *
268          * \details will decode and return string representation of protocol (matches DB enum)
269          *
270          * \param [in]   proto_id       NLRI protocol type id
271          *
272          * \return string representation for the protocol that matches the DB enum string value
273          *          empty will be returned if invalid/unknown.
274          */
275         std::string decodeNlriProtocolId(uint8_t proto_id);
276 
277         /**********************************************************************************//*
278          * Hash node descriptor info
279          *
280          * \details will produce a hash for the node descriptor.  Info hash_bin will be updated.
281          *
282          * \param [in/out]  info           Node descriptor information returned/updated
283          * \param [out]  hash_bin       Node descriptor information returned/updated
284          */
285         void genNodeHashId(node_descriptor &info);
286 
287     };
288 
289 } /* namespace bgp_msg */
290 
291 #endif //_OPENBMP_MPLINKSTATE_H_
292