From 309ec95c2ab31b309b3ccc69bc6a685241f9a2a6 Mon Sep 17 00:00:00 2001 From: Ojas Gupta Date: Sun, 19 Nov 2017 01:33:58 -0800 Subject: [PATCH 1/7] Added MPLS parsing feature to the library --- lib/bgp/parsebgp_bgp_common.h | 12 +- lib/bgp/parsebgp_bgp_update_mp_reach.c | 23 + .../parsebgp_bgp_update_mp_reach_link_state.c | 654 ++++++++++++++++++ .../parsebgp_bgp_update_mp_reach_link_state.h | 412 +++++++++++ 4 files changed, 1099 insertions(+), 2 deletions(-) create mode 100644 lib/bgp/parsebgp_bgp_update_mp_reach_link_state.c create mode 100644 lib/bgp/parsebgp_bgp_update_mp_reach_link_state.h diff --git a/lib/bgp/parsebgp_bgp_common.h b/lib/bgp/parsebgp_bgp_common.h index f17f1c5..2a1cdbb 100644 --- a/lib/bgp/parsebgp_bgp_common.h +++ b/lib/bgp/parsebgp_bgp_common.h @@ -40,7 +40,11 @@ typedef enum { /** IPv6 Address */ PARSEBGP_BGP_AFI_IPV6 = 2, - // TODO: add support for L2VPN, BGPLS + /** Layer 2 VPNs */ + PARSEBGP_BGP_AFI_L2VPN = 25, + + /** BGP Link State */ + PARSEBGP_BGP_AFI_BGPLS = 16388, } parsebgp_bgp_afi_t; @@ -55,7 +59,11 @@ typedef enum { /** Multicast */ PARSEBGP_BGP_SAFI_MULTICAST = 2, - // TODO: add support for EVPN, NLRI_LABEL + PARSEBGP_BGP_NLRI_LABEL = 4, + + PARSEBGP_BGP_SAFI_EVPN = 70, + + PARSEBGP_BGP_SAFI_BGPLS = 71, /** MPLS */ PARSEBGP_BGP_SAFI_MPLS = 128, diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach.c b/lib/bgp/parsebgp_bgp_update_mp_reach.c index 8eef012..be88500 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_reach.c +++ b/lib/bgp/parsebgp_bgp_update_mp_reach.c @@ -298,6 +298,29 @@ parsebgp_bgp_update_mp_reach_decode(parsebgp_opts_t *opts, buf += slen; break; + case PARSEBGP_BGP_AFI_BGPLS: + slen = len - nread; + if ((err = parsebgp_bgp_update_mp_reach_link_state_decode(opts, + msg, + buf, + &slen, + remain - nread)) + != PARSEBGP_OK) { + return err; + } + nread += slen; + buf += slen; + break; + + case PARSEBGP_BGP_AFI_L2VPN: + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, + buf, + nread, + remain - nread, + "Unsupported AFI (%d): L2VPN not implemented", + msg->afi); + break; + default: PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, nread, remain - nread, "Unsupported AFI (%d)", msg->afi); diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.c b/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.c new file mode 100644 index 0000000..51758a2 --- /dev/null +++ b/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.c @@ -0,0 +1,654 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ +#include "parsebgp_bgp_update_mp_reach_link_state.h" +#include "parsebgp_error.h" +#include "parsebgp_utils.h" +#include "parsebgp_bgp_update_mp_reach.h" +#include "../parsebgp_utils.h" +#include +#include +#include +#include + +parsebgp_error_t +parse_reach_link_state_nlri_node_val(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *node, + uint8_t *buf, + size_t *lenp) { + + size_t len = *lenp, nread = 0; + + // Read the nlri type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, node->type); + node->type = ntohs(node->type); + + // Read the nlri length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, node->len); + node->len = ntohs(node->len); + + switch (node->type) { + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_AS: + if (node->len != sizeof(node->node_value.asn)){ + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, node->node_value.asn); + node->node_value.asn = ntohs(node->node_value.asn); + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_BGP_LS_ID: + if (node->len != sizeof(node->node_value.bgp_ls_id)){ + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, node->node_value.bgp_ls_id); + node->node_value.bgp_ls_id = ntohs(node->node_value.bgp_ls_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + if (node->len != sizeof(node->node_value.ospf_area_Id)){ + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, node->node_value.ospf_area_Id); + node->node_value.ospf_area_Id = ntohs(node->node_value.ospf_area_Id); + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + if (node->len > 8) { + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + memcpy(node->node_value.igp_router_id, buf, node->len); + nread += node->len; + buf += node->len; + break; + + default: + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, + buf, + nread, + len, + "Unsupported NLRI node type (%d)", + node->type); + + } + + *lenp = nread; + return PARSEBGP_OK; +} + +parsebgp_error_t +parse_reach_link_state_nlri_node(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_link_state_t *msg, + uint8_t *buf, + size_t *lenp, size_t remain) { + + size_t len = *lenp, nread = 0, slen; + parsebgp_error_t err; + + // Read the node type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.node_nlri.type); + msg->nlri_ls.node_nlri.type = ntohs(msg->nlri_ls.node_nlri.type); + + // Read the node length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.node_nlri.len); + msg->nlri_ls.node_nlri.len = ntohs(msg->nlri_ls.node_nlri.len); + + msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt = 0; + + parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *node; + + while(nread < msg->nlri_ls.node_nlri.len) { + PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.node_nlri.local_node_desc.nodes, + sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + msg->nlri_ls.node_nlri.local_node_desc._nodes_alloc_cnt, + msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt + + 1); + + node = &msg->nlri_ls.node_nlri.local_node_desc.nodes[msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt]; + msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt += 1; + + slen = len - nread; + + if ((err = parse_reach_link_state_nlri_node_val( + opts, node, buf, &slen)) != + PARSEBGP_OK) { + return err; + } + + buf += slen; + nread += slen; + } + + *lenp = nread; + return PARSEBGP_OK; +} + +parsebgp_error_t +parse_reach_link_state_nlri_link_val(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t *link, + uint8_t *buf, + size_t *lenp) { + + size_t len = *lenp, nread = 0; + + // Read the nlri type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->type); + link->type = ntohs(link->type); + + // Read the nlri length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->len); + link->len = ntohs(link->len); + + switch (link->type) { + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_ID: + + if (link->len != 8){ + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ids.link_local_id); + link->link_ids.link_local_id = ntohs(link->link_ids.link_local_id); + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ids.link_remote_id); + link->link_ids.link_local_id = ntohs(link->link_ids.link_remote_id); + + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV4_INTF_ADDR: + if (link->len != 4){ + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ipv4_intf_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV4_NEI_ADDR: + if (link->len != 4){ + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ipv4_neigh_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV6_INTF_ADDR: + if (link->len != 16){ + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ipv6_intf_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV6_NEI_ADDR: + if (link->len != 16){ + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ipv6_neigh_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_MT_ID: + + if ((link->len % sizeof(uint16_t)) != 0) { + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + link->link_mt_id.ids_cnt = link->len / sizeof(uint16_t); + + PARSEBGP_MAYBE_REALLOC(link->link_mt_id.ids, + sizeof(uint16_t), + link->link_mt_id._ids_alloc_cnt, + link->link_mt_id.ids_cnt); + + int i; + for (i = 0; i < link->link_mt_id.ids_cnt; i++) { + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_mt_id.ids); + + link->link_mt_id.ids[i] = + ntohs(link->link_mt_id.ids[i]); + } + break; + + default: + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, + buf, + nread, + len, + "Unsupported NLRI node type (%d)", + link->type); + + } + + *lenp = nread; + return PARSEBGP_OK; +} + +parsebgp_error_t +parse_reach_link_state_nlri_link(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_link_state_t *msg, + uint8_t *buf, + size_t *lenp, size_t remain) { + + size_t len = *lenp, nread = 0, slen; + parsebgp_error_t err; + + // Read the node type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.local_node_desc.type); + msg->nlri_ls.link_nlri.local_node_desc.type = ntohs(msg->nlri_ls.link_nlri.local_node_desc.type); + + // Read the node length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.local_node_desc.len); + msg->nlri_ls.link_nlri.local_node_desc.len = ntohs(msg->nlri_ls.link_nlri.local_node_desc.len); + + msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt = 0; + + parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *node; + + while(nread < msg->nlri_ls.link_nlri.local_node_desc.len) { + PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.link_nlri.local_node_desc.nodes, + sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + msg->nlri_ls.link_nlri.local_node_desc._nodes_alloc_cnt, + msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt + + 1); + + node = &msg->nlri_ls.link_nlri.local_node_desc.nodes[msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt]; + msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt += 1; + + slen = len - nread; + + if ((err = parse_reach_link_state_nlri_node_val( + opts, node, buf, &slen)) != + PARSEBGP_OK) { + return err; + } + + buf += slen; + nread += slen; + } + + + // Read the node type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.remote_node_desc.type); + msg->nlri_ls.link_nlri.remote_node_desc.type = ntohs(msg->nlri_ls.link_nlri.remote_node_desc.type); + + // Read the node length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.remote_node_desc.len); + msg->nlri_ls.link_nlri.remote_node_desc.len = ntohs(msg->nlri_ls.link_nlri.remote_node_desc.len); + + msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt = 0; + + while(nread < msg->nlri_ls.link_nlri.remote_node_desc.len) { + PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.link_nlri.remote_node_desc.nodes, + sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + msg->nlri_ls.link_nlri.remote_node_desc._nodes_alloc_cnt, + msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt + + 1); + + node = &msg->nlri_ls.link_nlri.remote_node_desc.nodes[msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt]; + msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt += 1; + + slen = len - nread; + + if ((err = parse_reach_link_state_nlri_node_val( + opts, node, buf, &slen)) != + PARSEBGP_OK) { + return err; + } + + buf += slen; + nread += slen; + } + + + // Read the node type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.link_desc.type); + msg->nlri_ls.link_nlri.link_desc.type = ntohs(msg->nlri_ls.link_nlri.link_desc.type); + + // Read the node length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.link_desc.len); + msg->nlri_ls.link_nlri.link_desc.len = ntohs(msg->nlri_ls.link_nlri.link_desc.len); + + msg->nlri_ls.link_nlri.link_desc.links_cnt = 0; + + parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t *link; + + while(nread < msg->nlri_ls.link_nlri.link_desc.len) { + PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.link_nlri.link_desc.links, + sizeof(parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t), + msg->nlri_ls.link_nlri.link_desc._links_alloc_cnt, + msg->nlri_ls.link_nlri.link_desc.links_cnt + + 1); + + link = &msg->nlri_ls.link_nlri.link_desc.links[msg->nlri_ls.link_nlri.link_desc.links_cnt]; + msg->nlri_ls.link_nlri.link_desc.links_cnt += 1; + + slen = len - nread; + + if ((err = parse_reach_link_state_nlri_link_val( + opts, link, buf, &slen)) != + PARSEBGP_OK) { + return err; + } + + buf += slen; + nread += slen; + } + + *lenp = nread; + return PARSEBGP_OK; + +} + +parsebgp_error_t +parse_reach_link_state_nlri_prefix_val(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor_t *prefix, + uint8_t *buf, + size_t *lenp) { + + size_t len = *lenp, nread = 0; + + // Read the nlri type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, prefix->type); + prefix->type = ntohs(prefix->type); + + // Read the nlri length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, prefix->len); + prefix->len = ntohs(prefix->len); + + switch (prefix->type) { + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_MT_ID: + + if ((prefix->len % sizeof(uint16_t)) != 0) { + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + prefix->prefix_mt_id.ids_cnt = prefix->len / sizeof(uint16_t); + + PARSEBGP_MAYBE_REALLOC(prefix->prefix_mt_id.ids, + sizeof(uint16_t), + prefix->prefix_mt_id._ids_alloc_cnt, + prefix->prefix_mt_id.ids_cnt); + + int i; + for (i = 0; i < prefix->prefix_mt_id.ids_cnt; i++) { + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, prefix->prefix_mt_id.ids); + + prefix->prefix_mt_id.ids[i] = + ntohs(prefix->prefix_mt_id.ids[i]); + } + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_OSPF_ROUTE_TYPE: + if (prefix->len != sizeof(prefix->prefix_ospf_route_type)){ + PARSEBGP_RETURN_INVALID_MSG_ERR; + } + + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, prefix->prefix_ospf_route_type); + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO: + //TODO: Ask Alistair + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, + buf, + nread, + len, + "Unsupported NLRI node type (%d)", + prefix->type); + break; + + default: + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, + buf, + nread, + len, + "Unsupported NLRI node type (%d)", + prefix->type); + + } + + *lenp = nread; + return PARSEBGP_OK; +} + + +parsebgp_error_t +parse_reach_link_state_nlri_prefix(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_link_state_t *msg, + uint8_t *buf, + size_t *lenp, size_t remain) { + size_t len = *lenp, nread = 0, slen; + parsebgp_error_t err; + + // Read the node type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.prefix_nlri.local_node_desc.type); + msg->nlri_ls.prefix_nlri.local_node_desc.type = ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.type); + + // Read the node length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.prefix_nlri.local_node_desc.len); + msg->nlri_ls.prefix_nlri.local_node_desc.len = ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.len); + + msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt = 0; + + parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *node; + + while(nread < msg->nlri_ls.prefix_nlri.local_node_desc.len) { + PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.prefix_nlri.local_node_desc.nodes, + sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + msg->nlri_ls.prefix_nlri.local_node_desc._nodes_alloc_cnt, + msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt + + 1); + + node = &msg->nlri_ls.prefix_nlri.local_node_desc.nodes[msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt]; + msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt += 1; + + slen = len - nread; + + if ((err = parse_reach_link_state_nlri_node_val( + opts, node, buf, &slen)) != + PARSEBGP_OK) { + return err; + } + + buf += slen; + nread += slen; + } + + // Read the node type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.prefix_nlri.prefix_desc.type); + msg->nlri_ls.prefix_nlri.local_node_desc.type = ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.type); + + // Read the node length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.prefix_nlri.local_node_desc.len); + msg->nlri_ls.prefix_nlri.local_node_desc.len = ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.len); + + msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt = 0; + + parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor_t *prefix; + + while(nread < msg->nlri_ls.prefix_nlri.prefix_desc.len) { + PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.prefix_nlri.prefix_desc.pref, + sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + msg->nlri_ls.prefix_nlri.prefix_desc._pref_alloc_cnt, + msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt + + 1); + + prefix = &msg->nlri_ls.prefix_nlri.prefix_desc.pref[msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt]; + msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt += 1; + + slen = len - nread; + + if ((err = parse_reach_link_state_nlri_prefix_val( + opts, prefix, buf, &slen)) != + PARSEBGP_OK) { + return err; + } + + buf += slen; + nread += slen; + } + + *lenp = nread; + return PARSEBGP_OK; + +} + +parsebgp_error_t +parse_reach_link_state_nlri(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain) { + + size_t len = *lenp, nread = 0, slen; + parsebgp_error_t err; + msg->mp_reach_ls.mp_ls_cnt = 0; + + parsebgp_bgp_update_mp_reach_link_state_t *ls_nlri; + + /** + * Loop through all TLV's for the attribute + */ + while (nread < remain) { + + PARSEBGP_MAYBE_REALLOC(msg->mp_reach_ls._mp_ls_alloc_cnt, + sizeof(parsebgp_bgp_update_mp_reach_link_state_t), + msg->mp_reach_ls._mp_ls_alloc_cnt, + msg->mp_reach_ls.mp_ls_cnt + 1); + + ls_nlri = &msg->mp_reach_ls.mp_ls[msg->mp_reach_ls.mp_ls_cnt]; + msg->mp_reach_ls.mp_ls_cnt += 1; + + // Read the nlri type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, ls_nlri->nlri_type); + ls_nlri->nlri_type = ntohs(ls_nlri->nlri_type); + + // Read the nlri length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, ls_nlri->nlri_len); + ls_nlri->nlri_len = ntohs(ls_nlri->nlri_len); + + // Read the protocol id + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, ls_nlri->protocol_id); + + // Read the identifier + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, ls_nlri->identifier); + ls_nlri->identifier = ntohs(ls_nlri->identifier); + + slen = len - nread; + + /* + * Decode based on bgp-ls NLRI type + */ + switch (ls_nlri->nlri_type) { + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_NODE: + + if ((err = parse_reach_link_state_nlri_node( + opts, ls_nlri, buf, &slen, remain - nread)) != + PARSEBGP_OK) { + return err; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_LINK: + if ((err = parse_reach_link_state_nlri_link( + opts, ls_nlri, buf, &slen, remain - nread)) != + PARSEBGP_OK) { + return err; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_IPV4_PREFIX: + if ((err = parse_reach_link_state_nlri_prefix( + opts, ls_nlri, buf, &slen, remain - nread)) != + PARSEBGP_OK) { + return err; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_IPV6_PREFIX: + if ((err = parse_reach_link_state_nlri_prefix( + opts, ls_nlri, buf, &slen, remain - nread)) != + PARSEBGP_OK) { + return err; + } + + break; + + default: + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, nread, remain - nread, + "Unsupported NLRI type (%d)", ls_nlri->nlri_type); + + } + + nread += slen; + buf += slen; + } + + *lenp = nread; + return PARSEBGP_OK; +} + +parsebgp_error_t +parsebgp_bgp_update_mp_reach_link_state_decode(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain) { + + size_t len = *lenp, nread = 0, slen; + parsebgp_error_t err; + + if (msg->next_hop_len > len) { + return PARSEBGP_PARTIAL_MSG; + } + + memcpy(msg->next_hop, buf, msg->next_hop_len); + buf += msg->next_hop_len; + nread += msg->next_hop_len; + + switch (msg->safi) { + + case PARSEBGP_BGP_SAFI_BGPLS: + slen = len - nread; + if ((err = parse_reach_link_state_nlri(opts, msg, buf, &slen, + remain - nread)) != PARSEBGP_OK) { + return err; + } + nread += slen; + buf += slen; + break; + + default: + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, nread, remain - nread, + "Unsupported SAFI (%d)", msg->safi); + + } + + *lenp = nread; + return PARSEBGP_OK; +} + +parsebgp_error_t +parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_unreach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain) { + + + +} diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.h b/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.h new file mode 100644 index 0000000..292253c --- /dev/null +++ b/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.h @@ -0,0 +1,412 @@ +#ifndef __PARSEBGP_BGP_UPDATE_MP_MP_REACH_LINK_STATE_H +#define __PARSEBGP_BGP_UPDATE_MP_MP_REACH_LINK_STATE_H + +#include "parsebgp_bgp_common.h" +#include "parsebgp_error.h" +#include "parsebgp_opts.h" +#include "../parsebgp_opts.h" +#include "parsebgp_bgp_update_mp_reach.h" +#include "../parsebgp_error.h" +#include +#include + +/** + * Defines the BGP link state NLRI types + * https://tools.ietf.org/html/draft-ietf-idr-ls-distribution-10#section-3.2 + */ +typedef enum { + + /** NLRI TYPE: NODE NLRI */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_NODE = 1, + + /** NLRI TYPE: LINK NLRI */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_LINK = 2, + + /** NLRI TYPE: IPV4 PREFIX NLRI */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_IPV4_PREFIX = 3, + + /** NLRI TYPE: IPV^ PREFIX NLRI */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_IPV6_PREFIX = 4 + +} parsebgp_bgp_update_mp_reach_link_state_nlri_types_t; + +/** + * TODO: check if this is required + * Defines the NLRI protocol-id values + */ +typedef enum { + + /** NLRI information source protocol: IS-IS Level 1 */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_ISIS_L1 = 1, + + /** NLRI information source protocol: IS-IS Level 2 */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_ISIS_L2 = 2, + + /** NLRI information source protocol: OSPFv2 */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_OSPFV2 = 3, + + /** NLRI information source protocol: DIRECT */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_DIRECT = 4, + + /** NLRI information source protocol: Static configuration */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_STATIC = 5, + + /** NLRI information source protocol: OSPFv3 */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_OSPFV3 = 6, + +} parsebgp_bgp_update_mp_reach_link_state_protocol_ids_t; + +typedef enum { + + /** Routing Universe: Default Layer 3 Routing topology */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_DEF_LAYER_3_ROUTING_TOPOLOGY = 0, + +} parsebgp_bgp_update_mp_reach_link_state_identifier_t; + +/** + * Node descriptor Sub-TLV's + * Used by both remote and local node descriptors + */ +typedef enum { + //TODO: check this field + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_LOCAL_DESCR = + 256, ///< Local node descriptor + //TODO: check this field + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_REMOTE_DESCR = + 257, ///< Remote node descriptor + + /** Node Descriptor: Autonomous System (len = 4) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_AS = 512, + + /** Node Descriptor: BGP LS Identifier (len = 4) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_BGP_LS_ID = 513, + + /** Node Descriptor: OSPF Area ID (len = 4) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_OSPF_AREA_ID = 514, + + /** Node Descriptor: IGP Router ID (len = variable) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID = 515, + + //TODO: check this field + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_BGP_ROUTER_ID = 516 ///< BGP Router ID + ///< (draft-ietf-idr-bgpls-segment-routing-epe) +} parsebgp_bgp_update_mp_reach_link_state_node_descr_sub_types_t; + +/** + * Link Descriptor Sub-TLV's + */ +typedef enum { + + /** Link Descriptor: Link Local/Remote Identifiers 22/4 (rfc5307/1.1) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_ID = 258, + + /** Link Descriptor: IPv4 interface address 22/6 (rfc5305/3.2) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV4_INTF_ADDR = 259, + + /** Link Descriptor: IPv4 neighbor address 22/8 (rfc5305/3.3) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV4_NEI_ADDR = 260, + + /** Link Descriptor: IPv4 interface address 22/6 (rfc5305/3.2) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV6_INTF_ADDR = 261, + + /** Link Descriptor: IPv6 neighbor address 22/13 (rfc6119/4.3) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV6_NEI_ADDR = 262, + + /** Link Descriptor: Multi-Topology Identifier */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_MT_ID = 263 + +} parsebgp_bgp_update_mp_reach_link_state_link_descr_sub_types_t; + +/** + * Prefix Descriptor Sub-TLV's + */ +typedef enum prefix_descr_sub_types { + + /** Prefix Descriptor: Multi-Topology Identifier (len = variable) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_MT_ID = 263, + + /** Prefix Descriptor: OSPF Route Type (len=1) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_OSPF_ROUTE_TYPE = 264, + + /** Prefix Descriptor: IP Reachability Information (len=variable) */ + PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO = 265 + +} parsebgp_bgp_update_mp_reach_link_state_prefix_descr_sub_types_t; + +/** + * OSPF Route Types + */ +//TODO: Not sure if this is required +typedef enum ospf_route_types { + OSPF_RT_INTRA_AREA = 1, ///< Intra-Area + OSPF_RT_INTER_AREA, ///< Inter-Area + OSPF_RT_EXTERNAL_1, ///< External type 1 + OSPF_RT_EXTERNAL_2, ///< External type 2 + OSPF_RT_NSSA_1, ///< NSSA type 1 + OSPF_RT_NSSA_2 ///< NSSA type 2 +}; + +/** + * Node (local and remote) common fields + */ +typedef struct parsebgp_bgp_update_mp_reach_link_state_node_descriptor { + + /** Type of the node descriptor */ + uint16_t type; + + /** Length of the node descriptor */ + uint16_t len; + + union { + /** Node Descriptor: Autonomous System (len = 4) */ + uint32_t asn; + + /** Node Descriptor: BGP LS Identifier (len = 4) */ + uint32_t bgp_ls_id; + + /** Node Descriptor: OSPF Area ID (len = 4) */ + uint32_t ospf_area_Id; + + /** Node Descriptor: IGP Router ID (len = variable) */ + uint8_t igp_router_id[8]; + + } node_value; +} parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t; + +/** + * Link Descriptor common fields + */ +typedef struct parsebgp_bgp_update_mp_reach_link_state_link_descriptor { + + /** Type of the link descriptor */ + uint16_t type; + + /** Length of the link descriptor */ + uint16_t len; + + struct { + /** Link Local ID */ + uint32_t link_local_id; + + /** Link Remote ID */ + uint32_t link_remote_id; ///< Link Remote ID + } link_ids; + + /** ipv4 Interface binary address */ + uint8_t link_ipv4_intf_addr[4]; + + /** ipv4 Neighbor binary address */ + uint8_t link_ipv4_neigh_addr[4]; + + /** ipv6 Interface binary address */ + uint8_t link_ipv6_intf_addr[16]; + + /** ipv6 Neighbor binary address */ + uint8_t link_ipv6_neigh_addr[16]; + + /** Multi-Topology ID (len=variable) */ + struct { + + /** Array of mt_ids */ + uint16_t *ids; + + /** Allocated length of ids */ + int _ids_alloc_cnt; + + /** Populated ids count */ + int ids_cnt; + + } link_mt_id; + +} parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t; + +/** + * Prefix descriptor common fields + */ +typedef struct parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor { + + /** Type of the prefix descriptor */ + uint16_t type; + + /** Length of the prefix descriptor */ + uint16_t len; + + /** Multi-Topology ID (len=variable) */ + struct { + + /** Array of mt_ids */ + uint16_t *ids; + + /** Allocated length of ids */ + int _ids_alloc_cnt; + + /** Populated ids count */ + int ids_cnt; + + } prefix_mt_id; + + /** OSPF Route type */ + uint8_t prefix_ospf_route_type; + + struct { + uint8_t prefix_len; + + /** Array of ip_prefix */ + uint8_t *ip_prefix; + + /** Allocated length of ip_prefix */ + int _ip_prefix_cnt; + + /** Populated ip_prefix count */ + int ip_prefix_cnt; + + }prefix_ip_reach_info; + +} parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor_t; + +typedef struct parsebgp_bgp_update_mp_reach_link_state { + + /** AFI : 16388, SAFI : 71 */ + + /** Type of NLRI: node, link, ipv4 prefix, ipv6 prefix */ + uint16_t nlri_type; + + /** Length of the rest of the NLRI excluding type and itslef */ + uint16_t nlri_len; + + /** Contains NLRI information source protocol */ + uint8_t protocol_id; + + /** Identifier has info of Routing Universe */ + uint64_t identifier; + + struct nlri_ls { + + struct node_nlri { + + /** type of the node descriptor */ + uint16_t type; + + /** Length of node descriptor (len = variable) */ + uint16_t len; + + struct { + /** Array of node descriptors */ + parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *nodes; + + /** Allocated length of nodes */ + int _nodes_alloc_cnt; + + /** Populated length of nodes */ + int nodes_cnt; + } local_node_desc; + + } node_nlri; + + struct link_nlri { + + struct { + /** type of the local node descriptor */ + uint16_t type; + + /** Length of local node descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *nodes; + + /** Allocated length of nodes */ + int _nodes_alloc_cnt; + + /** Populated length of nodes */ + int nodes_cnt; + } local_node_desc; + + struct { + /** type of the remote node descriptor */ + uint16_t type; + + /** Length of remote node descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *nodes; + + /** Allocated length of nodes */ + int _nodes_alloc_cnt; + + /** Populated length of nodes */ + int nodes_cnt; + } remote_node_desc; + + struct { + /** type of the link descriptor */ + uint16_t type; + + /** Length of link descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t *links; + + /** Allocated length of nodes */ + int _links_alloc_cnt; + + /** Populated length of nodes */ + int links_cnt; + } link_desc; + + } link_nlri; + + struct prefix_nlri_ipv4_ipv6 { + + struct { + /** type of the prefix descriptor */ + uint16_t type; + + /** Length of prefix descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *nodes; + + /** Allocated length of nodes */ + int _nodes_alloc_cnt; + + /** Populated length of nodes */ + int nodes_cnt; + } local_node_desc; + + struct { + + /** type of the prefix descriptor */ + uint16_t type; + + /** Length of prefix descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor_t *pref; + + /** Allocated length of nodes */ + int _pref_alloc_cnt; + + /** Populated length of nodes */ + int pref_cnt; + } prefix_desc; + + } prefix_nlri; + + } nlri_ls; + +} parsebgp_bgp_update_mp_reach_link_state_t; + +/** Decode an MP_REACH message */ +parsebgp_error_t +parsebgp_bgp_update_mp_reach_link_state_decode(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain); + +#endif __PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_H \ No newline at end of file From 33566a3844e89dc9ff178d6c9598693502eceb33 Mon Sep 17 00:00:00 2001 From: Ojas Gupta Date: Mon, 20 Nov 2017 11:01:58 -0800 Subject: [PATCH 2/7] Updated MPLS with unreach capability --- lib/bgp/Makefile.am | 7 +- ....c => parsebgp_bgp_update_mp_link_state.c} | 288 ++++++++---- lib/bgp/parsebgp_bgp_update_mp_link_state.h | 126 ++++++ lib/bgp/parsebgp_bgp_update_mp_reach.c | 24 + lib/bgp/parsebgp_bgp_update_mp_reach.h | 283 ++++++++++++ .../parsebgp_bgp_update_mp_reach_link_state.h | 412 ------------------ 6 files changed, 642 insertions(+), 498 deletions(-) rename lib/bgp/{parsebgp_bgp_update_mp_reach_link_state.c => parsebgp_bgp_update_mp_link_state.c} (67%) create mode 100644 lib/bgp/parsebgp_bgp_update_mp_link_state.h delete mode 100644 lib/bgp/parsebgp_bgp_update_mp_reach_link_state.h diff --git a/lib/bgp/Makefile.am b/lib/bgp/Makefile.am index d6f761e..32cf5ae 100644 --- a/lib/bgp/Makefile.am +++ b/lib/bgp/Makefile.am @@ -39,7 +39,8 @@ include_HEADERS = \ parsebgp_bgp_route_refresh.h \ parsebgp_bgp_update.h \ parsebgp_bgp_update_ext_communities.h \ - parsebgp_bgp_update_mp_reach.h + parsebgp_bgp_update_mp_reach.h \ + parsebgp_bgp_update_mp_link_state.h noinst_LTLIBRARIES = libparsebgp_bgp.la @@ -61,6 +62,8 @@ libparsebgp_bgp_la_SOURCES = \ parsebgp_bgp_update_ext_communities.c \ parsebgp_bgp_update_ext_communities.h \ parsebgp_bgp_update_mp_reach.c \ - parsebgp_bgp_update_mp_reach.h + parsebgp_bgp_update_mp_reach.h \ + parsebgp_bgp_update_mp_link_state.c \ + parsebgp_bgp_update_mp_link_state.h CLEANFILES = *~ diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.c b/lib/bgp/parsebgp_bgp_update_mp_link_state.c similarity index 67% rename from lib/bgp/parsebgp_bgp_update_mp_reach_link_state.c rename to lib/bgp/parsebgp_bgp_update_mp_link_state.c index 51758a2..d0c2429 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.c +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.c @@ -6,21 +6,21 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html * */ -#include "parsebgp_bgp_update_mp_reach_link_state.h" +#include "parsebgp_bgp_update_mp_link_state.h" +#include "parsebgp_bgp_update_mp_reach.h" #include "parsebgp_error.h" #include "parsebgp_utils.h" -#include "parsebgp_bgp_update_mp_reach.h" -#include "../parsebgp_utils.h" +#include "parsebgp_utils.h" #include #include #include #include -parsebgp_error_t -parse_reach_link_state_nlri_node_val(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *node, - uint8_t *buf, - size_t *lenp) { +static parsebgp_error_t +parse_link_state_nlri_node_val(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_link_state_node_descriptor_t *node, + uint8_t *buf, + size_t *lenp) { size_t len = *lenp, nread = 0; @@ -34,7 +34,7 @@ parse_reach_link_state_nlri_node_val(parsebgp_opts_t *opts, switch (node->type) { - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_AS: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: if (node->len != sizeof(node->node_value.asn)){ PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -43,7 +43,7 @@ parse_reach_link_state_nlri_node_val(parsebgp_opts_t *opts, node->node_value.asn = ntohs(node->node_value.asn); break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_BGP_LS_ID: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: if (node->len != sizeof(node->node_value.bgp_ls_id)){ PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -52,7 +52,7 @@ parse_reach_link_state_nlri_node_val(parsebgp_opts_t *opts, node->node_value.bgp_ls_id = ntohs(node->node_value.bgp_ls_id); break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: if (node->len != sizeof(node->node_value.ospf_area_Id)){ PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -61,7 +61,7 @@ parse_reach_link_state_nlri_node_val(parsebgp_opts_t *opts, node->node_value.ospf_area_Id = ntohs(node->node_value.ospf_area_Id); break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: if (node->len > 8) { PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -85,11 +85,11 @@ parse_reach_link_state_nlri_node_val(parsebgp_opts_t *opts, return PARSEBGP_OK; } -parsebgp_error_t -parse_reach_link_state_nlri_node(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_reach_link_state_t *msg, - uint8_t *buf, - size_t *lenp, size_t remain) { +static parsebgp_error_t +parse_link_state_nlri_node(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_link_state_t *msg, + uint8_t *buf, + size_t *lenp, size_t remain) { size_t len = *lenp, nread = 0, slen; parsebgp_error_t err; @@ -104,11 +104,11 @@ parse_reach_link_state_nlri_node(parsebgp_opts_t *opts, msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt = 0; - parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *node; + parsebgp_bgp_update_mp_link_state_node_descriptor_t *node; while(nread < msg->nlri_ls.node_nlri.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.node_nlri.local_node_desc.nodes, - sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.node_nlri.local_node_desc._nodes_alloc_cnt, msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt + 1); @@ -118,7 +118,7 @@ parse_reach_link_state_nlri_node(parsebgp_opts_t *opts, slen = len - nread; - if ((err = parse_reach_link_state_nlri_node_val( + if ((err = parse_link_state_nlri_node_val( opts, node, buf, &slen)) != PARSEBGP_OK) { return err; @@ -132,11 +132,11 @@ parse_reach_link_state_nlri_node(parsebgp_opts_t *opts, return PARSEBGP_OK; } -parsebgp_error_t -parse_reach_link_state_nlri_link_val(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t *link, - uint8_t *buf, - size_t *lenp) { +static parsebgp_error_t +parse_link_state_nlri_link_val(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_link_state_link_descriptor_t *link, + uint8_t *buf, + size_t *lenp) { size_t len = *lenp, nread = 0; @@ -150,7 +150,7 @@ parse_reach_link_state_nlri_link_val(parsebgp_opts_t *opts, switch (link->type) { - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_ID: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_ID: if (link->len != 8){ PARSEBGP_RETURN_INVALID_MSG_ERR; @@ -164,7 +164,7 @@ parse_reach_link_state_nlri_link_val(parsebgp_opts_t *opts, break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV4_INTF_ADDR: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_INTF_ADDR: if (link->len != 4){ PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -172,7 +172,7 @@ parse_reach_link_state_nlri_link_val(parsebgp_opts_t *opts, PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ipv4_intf_addr); break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV4_NEI_ADDR: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_NEI_ADDR: if (link->len != 4){ PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -180,7 +180,7 @@ parse_reach_link_state_nlri_link_val(parsebgp_opts_t *opts, PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ipv4_neigh_addr); break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV6_INTF_ADDR: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_INTF_ADDR: if (link->len != 16){ PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -188,7 +188,7 @@ parse_reach_link_state_nlri_link_val(parsebgp_opts_t *opts, PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ipv6_intf_addr); break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV6_NEI_ADDR: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_NEI_ADDR: if (link->len != 16){ PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -196,7 +196,7 @@ parse_reach_link_state_nlri_link_val(parsebgp_opts_t *opts, PARSEBGP_DESERIALIZE_VAL(buf, len, nread, link->link_ipv6_neigh_addr); break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_MT_ID: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_MT_ID: if ((link->len % sizeof(uint16_t)) != 0) { PARSEBGP_RETURN_INVALID_MSG_ERR; @@ -233,11 +233,11 @@ parse_reach_link_state_nlri_link_val(parsebgp_opts_t *opts, return PARSEBGP_OK; } -parsebgp_error_t -parse_reach_link_state_nlri_link(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_reach_link_state_t *msg, - uint8_t *buf, - size_t *lenp, size_t remain) { +static parsebgp_error_t +parse_link_state_nlri_link(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_link_state_t *msg, + uint8_t *buf, + size_t *lenp, size_t remain) { size_t len = *lenp, nread = 0, slen; parsebgp_error_t err; @@ -252,11 +252,11 @@ parse_reach_link_state_nlri_link(parsebgp_opts_t *opts, msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt = 0; - parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *node; + parsebgp_bgp_update_mp_link_state_node_descriptor_t *node; while(nread < msg->nlri_ls.link_nlri.local_node_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.link_nlri.local_node_desc.nodes, - sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.link_nlri.local_node_desc._nodes_alloc_cnt, msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt + 1); @@ -266,7 +266,7 @@ parse_reach_link_state_nlri_link(parsebgp_opts_t *opts, slen = len - nread; - if ((err = parse_reach_link_state_nlri_node_val( + if ((err = parse_link_state_nlri_node_val( opts, node, buf, &slen)) != PARSEBGP_OK) { return err; @@ -289,7 +289,7 @@ parse_reach_link_state_nlri_link(parsebgp_opts_t *opts, while(nread < msg->nlri_ls.link_nlri.remote_node_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.link_nlri.remote_node_desc.nodes, - sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.link_nlri.remote_node_desc._nodes_alloc_cnt, msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt + 1); @@ -299,7 +299,7 @@ parse_reach_link_state_nlri_link(parsebgp_opts_t *opts, slen = len - nread; - if ((err = parse_reach_link_state_nlri_node_val( + if ((err = parse_link_state_nlri_node_val( opts, node, buf, &slen)) != PARSEBGP_OK) { return err; @@ -320,11 +320,11 @@ parse_reach_link_state_nlri_link(parsebgp_opts_t *opts, msg->nlri_ls.link_nlri.link_desc.links_cnt = 0; - parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t *link; + parsebgp_bgp_update_mp_link_state_link_descriptor_t *link; while(nread < msg->nlri_ls.link_nlri.link_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.link_nlri.link_desc.links, - sizeof(parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t), + sizeof(parsebgp_bgp_update_mp_link_state_link_descriptor_t), msg->nlri_ls.link_nlri.link_desc._links_alloc_cnt, msg->nlri_ls.link_nlri.link_desc.links_cnt + 1); @@ -334,7 +334,7 @@ parse_reach_link_state_nlri_link(parsebgp_opts_t *opts, slen = len - nread; - if ((err = parse_reach_link_state_nlri_link_val( + if ((err = parse_link_state_nlri_link_val( opts, link, buf, &slen)) != PARSEBGP_OK) { return err; @@ -349,11 +349,11 @@ parse_reach_link_state_nlri_link(parsebgp_opts_t *opts, } -parsebgp_error_t -parse_reach_link_state_nlri_prefix_val(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor_t *prefix, - uint8_t *buf, - size_t *lenp) { +static parsebgp_error_t +parse_link_state_nlri_prefix_val(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_link_state_prefix_descriptor_t *prefix, + uint8_t *buf, + size_t *lenp) { size_t len = *lenp, nread = 0; @@ -367,7 +367,7 @@ parse_reach_link_state_nlri_prefix_val(parsebgp_opts_t *opts, switch (prefix->type) { - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_MT_ID: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_MT_ID: if ((prefix->len % sizeof(uint16_t)) != 0) { PARSEBGP_RETURN_INVALID_MSG_ERR; @@ -390,7 +390,7 @@ parse_reach_link_state_nlri_prefix_val(parsebgp_opts_t *opts, } break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_OSPF_ROUTE_TYPE: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_OSPF_ROUTE_TYPE: if (prefix->len != sizeof(prefix->prefix_ospf_route_type)){ PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -398,7 +398,7 @@ parse_reach_link_state_nlri_prefix_val(parsebgp_opts_t *opts, PARSEBGP_DESERIALIZE_VAL(buf, len, nread, prefix->prefix_ospf_route_type); break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO: //TODO: Ask Alistair PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, @@ -423,11 +423,11 @@ parse_reach_link_state_nlri_prefix_val(parsebgp_opts_t *opts, } -parsebgp_error_t -parse_reach_link_state_nlri_prefix(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_reach_link_state_t *msg, - uint8_t *buf, - size_t *lenp, size_t remain) { +static parsebgp_error_t +parse_link_state_nlri_prefix(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_link_state_t *msg, + uint8_t *buf, + size_t *lenp, size_t remain) { size_t len = *lenp, nread = 0, slen; parsebgp_error_t err; @@ -441,11 +441,11 @@ parse_reach_link_state_nlri_prefix(parsebgp_opts_t *opts, msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt = 0; - parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *node; + parsebgp_bgp_update_mp_link_state_node_descriptor_t *node; while(nread < msg->nlri_ls.prefix_nlri.local_node_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.prefix_nlri.local_node_desc.nodes, - sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.prefix_nlri.local_node_desc._nodes_alloc_cnt, msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt + 1); @@ -455,7 +455,7 @@ parse_reach_link_state_nlri_prefix(parsebgp_opts_t *opts, slen = len - nread; - if ((err = parse_reach_link_state_nlri_node_val( + if ((err = parse_link_state_nlri_node_val( opts, node, buf, &slen)) != PARSEBGP_OK) { return err; @@ -475,11 +475,11 @@ parse_reach_link_state_nlri_prefix(parsebgp_opts_t *opts, msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt = 0; - parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor_t *prefix; + parsebgp_bgp_update_mp_link_state_prefix_descriptor_t *prefix; while(nread < msg->nlri_ls.prefix_nlri.prefix_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.prefix_nlri.prefix_desc.pref, - sizeof(parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t), + sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.prefix_nlri.prefix_desc._pref_alloc_cnt, msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt + 1); @@ -489,7 +489,7 @@ parse_reach_link_state_nlri_prefix(parsebgp_opts_t *opts, slen = len - nread; - if ((err = parse_reach_link_state_nlri_prefix_val( + if ((err = parse_link_state_nlri_prefix_val( opts, prefix, buf, &slen)) != PARSEBGP_OK) { return err; @@ -504,31 +504,31 @@ parse_reach_link_state_nlri_prefix(parsebgp_opts_t *opts, } -parsebgp_error_t +static parsebgp_error_t parse_reach_link_state_nlri(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_reach_t *msg, - uint8_t *buf, - size_t *lenp, - size_t remain) { + parsebgp_bgp_update_mp_reach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain) { size_t len = *lenp, nread = 0, slen; parsebgp_error_t err; - msg->mp_reach_ls.mp_ls_cnt = 0; + msg->mp_ls.mp_ls_cnt = 0; - parsebgp_bgp_update_mp_reach_link_state_t *ls_nlri; + parsebgp_bgp_update_mp_link_state_t *ls_nlri; /** * Loop through all TLV's for the attribute */ while (nread < remain) { - PARSEBGP_MAYBE_REALLOC(msg->mp_reach_ls._mp_ls_alloc_cnt, - sizeof(parsebgp_bgp_update_mp_reach_link_state_t), - msg->mp_reach_ls._mp_ls_alloc_cnt, - msg->mp_reach_ls.mp_ls_cnt + 1); + PARSEBGP_MAYBE_REALLOC(msg->mp_ls.mp_ls, + sizeof(parsebgp_bgp_update_mp_link_state_t), + msg->mp_ls._mp_ls_alloc_cnt, + msg->mp_ls.mp_ls_cnt + 1); - ls_nlri = &msg->mp_reach_ls.mp_ls[msg->mp_reach_ls.mp_ls_cnt]; - msg->mp_reach_ls.mp_ls_cnt += 1; + ls_nlri = &msg->mp_ls.mp_ls[msg->mp_ls.mp_ls_cnt]; + msg->mp_ls.mp_ls_cnt += 1; // Read the nlri type PARSEBGP_DESERIALIZE_VAL(buf, len, nread, ls_nlri->nlri_type); @@ -551,9 +551,9 @@ parse_reach_link_state_nlri(parsebgp_opts_t *opts, * Decode based on bgp-ls NLRI type */ switch (ls_nlri->nlri_type) { - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_NODE: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_NODE: - if ((err = parse_reach_link_state_nlri_node( + if ((err = parse_link_state_nlri_node( opts, ls_nlri, buf, &slen, remain - nread)) != PARSEBGP_OK) { return err; @@ -561,8 +561,8 @@ parse_reach_link_state_nlri(parsebgp_opts_t *opts, break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_LINK: - if ((err = parse_reach_link_state_nlri_link( + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_LINK: + if ((err = parse_link_state_nlri_link( opts, ls_nlri, buf, &slen, remain - nread)) != PARSEBGP_OK) { return err; @@ -570,8 +570,8 @@ parse_reach_link_state_nlri(parsebgp_opts_t *opts, break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_IPV4_PREFIX: - if ((err = parse_reach_link_state_nlri_prefix( + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV4_PREFIX: + if ((err = parse_link_state_nlri_prefix( opts, ls_nlri, buf, &slen, remain - nread)) != PARSEBGP_OK) { return err; @@ -579,8 +579,106 @@ parse_reach_link_state_nlri(parsebgp_opts_t *opts, break; - case PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_IPV6_PREFIX: - if ((err = parse_reach_link_state_nlri_prefix( + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV6_PREFIX: + if ((err = parse_link_state_nlri_prefix( + opts, ls_nlri, buf, &slen, remain - nread)) != + PARSEBGP_OK) { + return err; + } + + break; + + default: + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, nread, remain - nread, + "Unsupported NLRI type (%d)", ls_nlri->nlri_type); + + } + + nread += slen; + buf += slen; + } + + *lenp = nread; + return PARSEBGP_OK; +} + +static parsebgp_error_t +parse_unreach_link_state_nlri(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_unreach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain) { + + size_t len = *lenp, nread = 0, slen; + parsebgp_error_t err; + msg->mp_ls.mp_ls_cnt = 0; + + parsebgp_bgp_update_mp_link_state_t *ls_nlri; + + /** + * Loop through all TLV's for the attribute + */ + while (nread < remain) { + + PARSEBGP_MAYBE_REALLOC(msg->mp_ls.mp_ls, + sizeof(parsebgp_bgp_update_mp_link_state_t), + msg->mp_ls._mp_ls_alloc_cnt, + msg->mp_ls.mp_ls_cnt + 1); + + ls_nlri = &msg->mp_ls.mp_ls[msg->mp_ls.mp_ls_cnt]; + msg->mp_ls.mp_ls_cnt += 1; + + // Read the nlri type + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, ls_nlri->nlri_type); + ls_nlri->nlri_type = ntohs(ls_nlri->nlri_type); + + // Read the nlri length + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, ls_nlri->nlri_len); + ls_nlri->nlri_len = ntohs(ls_nlri->nlri_len); + + // Read the protocol id + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, ls_nlri->protocol_id); + + // Read the identifier + PARSEBGP_DESERIALIZE_VAL(buf, len, nread, ls_nlri->identifier); + ls_nlri->identifier = ntohs(ls_nlri->identifier); + + slen = len - nread; + + /* + * Decode based on bgp-ls NLRI type + */ + switch (ls_nlri->nlri_type) { + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_NODE: + + if ((err = parse_link_state_nlri_node( + opts, ls_nlri, buf, &slen, remain - nread)) != + PARSEBGP_OK) { + return err; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_LINK: + if ((err = parse_link_state_nlri_link( + opts, ls_nlri, buf, &slen, remain - nread)) != + PARSEBGP_OK) { + return err; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV4_PREFIX: + if ((err = parse_link_state_nlri_prefix( + opts, ls_nlri, buf, &slen, remain - nread)) != + PARSEBGP_OK) { + return err; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV6_PREFIX: + if ((err = parse_link_state_nlri_prefix( opts, ls_nlri, buf, &slen, remain - nread)) != PARSEBGP_OK) { return err; @@ -649,6 +747,28 @@ parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, size_t *lenp, size_t remain) { + size_t len = *lenp, nread = 0, slen; + parsebgp_error_t err; + + switch (msg->safi) { + + case PARSEBGP_BGP_SAFI_BGPLS: + slen = len - nread; + if ((err = parse_unreach_link_state_nlri(opts, msg, buf, &slen, + remain - nread)) != PARSEBGP_OK) { + return err; + } + nread += slen; + buf += slen; + break; + + default: + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, nread, remain - nread, + "Unsupported SAFI (%d)", msg->safi); + } + + *lenp = nread; + return PARSEBGP_OK; } diff --git a/lib/bgp/parsebgp_bgp_update_mp_link_state.h b/lib/bgp/parsebgp_bgp_update_mp_link_state.h new file mode 100644 index 0000000..6e1998c --- /dev/null +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.h @@ -0,0 +1,126 @@ +#ifndef __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H +#define __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H + +#include "parsebgp_bgp_common.h" +#include "parsebgp_error.h" +#include "parsebgp_opts.h" +#include "parsebgp_bgp_update_mp_reach.h" +#include +#include + +/** + * Defines the BGP link state NLRI types + * https://tools.ietf.org/html/draft-ietf-idr-ls-distribution-10#section-3.2 + */ +typedef enum { + + /** NLRI TYPE: NODE NLRI */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_NODE = 1, + + /** NLRI TYPE: LINK NLRI */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_LINK = 2, + + /** NLRI TYPE: IPV4 PREFIX NLRI */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV4_PREFIX = 3, + + /** NLRI TYPE: IPV^ PREFIX NLRI */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV6_PREFIX = 4 + +} parsebgp_bgp_update_mp_link_state_nlri_types_t; + + +typedef enum { + + /** Routing Universe: Default Layer 3 Routing topology */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_DEF_LAYER_3_ROUTING_TOPOLOGY = 0, + +} parsebgp_bgp_update_mp_link_state_identifier_t; + +/** + * Node descriptor Sub-TLV's + * Used by both remote and local node descriptors + */ +typedef enum { + //TODO: check this field + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_LOCAL_DESCR = + 256, ///< Local node descriptor + //TODO: check this field + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_REMOTE_DESCR = + 257, ///< Remote node descriptor + + /** Node Descriptor: Autonomous System (len = 4) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS = 512, + + /** Node Descriptor: BGP LS Identifier (len = 4) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID = 513, + + /** Node Descriptor: OSPF Area ID (len = 4) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID = 514, + + /** Node Descriptor: IGP Router ID (len = variable) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID = 515, + + //TODO: check this field + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_ROUTER_ID = 516 ///< BGP Router ID + ///< (draft-ietf-idr-bgpls-segment-routing-epe) +} parsebgp_bgp_update_mp_link_state_node_descr_sub_types_t; + +/** + * Link Descriptor Sub-TLV's + */ +typedef enum { + + /** Link Descriptor: Link Local/Remote Identifiers 22/4 (rfc5307/1.1) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_ID = 258, + + /** Link Descriptor: IPv4 interface address 22/6 (rfc5305/3.2) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_INTF_ADDR = 259, + + /** Link Descriptor: IPv4 neighbor address 22/8 (rfc5305/3.3) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_NEI_ADDR = 260, + + /** Link Descriptor: IPv4 interface address 22/6 (rfc5305/3.2) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_INTF_ADDR = 261, + + /** Link Descriptor: IPv6 neighbor address 22/13 (rfc6119/4.3) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_NEI_ADDR = 262, + + /** Link Descriptor: Multi-Topology Identifier */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_MT_ID = 263 + +} parsebgp_bgp_update_mp_link_state_link_descr_sub_types_t; + +/** + * Prefix Descriptor Sub-TLV's + */ +typedef enum { + + /** Prefix Descriptor: Multi-Topology Identifier (len = variable) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_MT_ID = 263, + + /** Prefix Descriptor: OSPF Route Type (len=1) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_OSPF_ROUTE_TYPE = 264, + + /** Prefix Descriptor: IP Reachability Information (len=variable) */ + PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO = 265 + +} parsebgp_bgp_update_mp_link_state_prefix_descr_sub_types_t; + + +/** Decode an MP_REACH message */ +parsebgp_error_t +parsebgp_bgp_update_mp_reach_link_state_decode(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_reach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain); + +/** Decode an MP_REACH message */ +parsebgp_error_t +parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, + parsebgp_bgp_update_mp_unreach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain); + +#endif __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H \ No newline at end of file diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach.c b/lib/bgp/parsebgp_bgp_update_mp_reach.c index be88500..3dea941 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_reach.c +++ b/lib/bgp/parsebgp_bgp_update_mp_reach.c @@ -25,6 +25,7 @@ */ #include "parsebgp_bgp_update_mp_reach.h" +#include "parsebgp_bgp_update_mp_link_state.h" #include "parsebgp_error.h" #include "parsebgp_utils.h" #include @@ -410,6 +411,29 @@ parsebgp_bgp_update_mp_unreach_decode(parsebgp_opts_t *opts, buf += slen; break; + case PARSEBGP_BGP_AFI_BGPLS: + slen = len - nread; + if ((err = parsebgp_bgp_update_mp_unreach_link_state_decode(opts, + msg, + buf, + &slen, + remain - nread)) + != PARSEBGP_OK) { + return err; + } + nread += slen; + buf += slen; + break; + + case PARSEBGP_BGP_AFI_L2VPN: + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, + buf, + nread, + remain - nread, + "Unsupported AFI (%d): L2VPN not implemented", + msg->afi); + break; + default: PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, nread, remain - nread, "Unsupported AFI (%d)", msg->afi); diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach.h b/lib/bgp/parsebgp_bgp_update_mp_reach.h index e3bdca1..4c813a5 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_reach.h +++ b/lib/bgp/parsebgp_bgp_update_mp_reach.h @@ -28,11 +28,267 @@ #define __PARSEBGP_BGP_UPDATE_MP_REACH_H #include "parsebgp_bgp_common.h" +//#include "parsebgp_bgp_update_mp_link_state.h" #include "parsebgp_error.h" #include "parsebgp_opts.h" #include #include +/** + * Node (local and remote) common fields + */ +typedef struct parsebgp_bgp_update_mp_link_state_node_descriptor { + + /** Type of the node descriptor */ + uint16_t type; + + /** Length of the node descriptor */ + uint16_t len; + + union { + /** Node Descriptor: Autonomous System (len = 4) */ + uint32_t asn; + + /** Node Descriptor: BGP LS Identifier (len = 4) */ + uint32_t bgp_ls_id; + + /** Node Descriptor: OSPF Area ID (len = 4) */ + uint32_t ospf_area_Id; + + /** Node Descriptor: IGP Router ID (len = variable) */ + uint8_t igp_router_id[8]; + + } node_value; +} parsebgp_bgp_update_mp_link_state_node_descriptor_t; + +/** + * Link Descriptor common fields + */ +typedef struct parsebgp_bgp_update_mp_link_state_link_descriptor { + + /** Type of the link descriptor */ + uint16_t type; + + /** Length of the link descriptor */ + uint16_t len; + + struct { + /** Link Local ID */ + uint32_t link_local_id; + + /** Link Remote ID */ + uint32_t link_remote_id; ///< Link Remote ID + } link_ids; + + /** ipv4 Interface binary address */ + uint8_t link_ipv4_intf_addr[4]; + + /** ipv4 Neighbor binary address */ + uint8_t link_ipv4_neigh_addr[4]; + + /** ipv6 Interface binary address */ + uint8_t link_ipv6_intf_addr[16]; + + /** ipv6 Neighbor binary address */ + uint8_t link_ipv6_neigh_addr[16]; + + /** Multi-Topology ID (len=variable) */ + struct { + + /** Array of mt_ids */ + uint16_t *ids; + + /** Allocated length of ids */ + int _ids_alloc_cnt; + + /** Populated ids count */ + int ids_cnt; + + } link_mt_id; + +} parsebgp_bgp_update_mp_link_state_link_descriptor_t; + +/** + * Prefix descriptor common fields + */ +typedef struct parsebgp_bgp_update_mp_link_state_prefix_descriptor { + + /** Type of the prefix descriptor */ + uint16_t type; + + /** Length of the prefix descriptor */ + uint16_t len; + + /** Multi-Topology ID (len=variable) */ + struct { + + /** Array of mt_ids */ + uint16_t *ids; + + /** Allocated length of ids */ + int _ids_alloc_cnt; + + /** Populated ids count */ + int ids_cnt; + + } prefix_mt_id; + + /** OSPF Route type */ + uint8_t prefix_ospf_route_type; + + struct { + uint8_t prefix_len; + + /** Array of ip_prefix */ + uint8_t *ip_prefix; + + /** Allocated length of ip_prefix */ + int _ip_prefix_cnt; + + /** Populated ip_prefix count */ + int ip_prefix_cnt; + + }prefix_ip_reach_info; + +} parsebgp_bgp_update_mp_link_state_prefix_descriptor_t; + +typedef struct parsebgp_bgp_update_mp_link_state { + + /** AFI : 16388, SAFI : 71 */ + + /** Type of NLRI: node, link, ipv4 prefix, ipv6 prefix */ + uint16_t nlri_type; + + /** Length of the rest of the NLRI excluding type and itslef */ + uint16_t nlri_len; + + /** Contains NLRI information source protocol */ + uint8_t protocol_id; + + /** Identifier has info of Routing Universe */ + uint64_t identifier; + + struct nlri_ls { + + struct node_nlri { + + /** type of the node descriptor */ + uint16_t type; + + /** Length of node descriptor (len = variable) */ + uint16_t len; + + struct { + /** Array of node descriptors */ + parsebgp_bgp_update_mp_link_state_node_descriptor_t *nodes; + + /** Allocated length of nodes */ + int _nodes_alloc_cnt; + + /** Populated length of nodes */ + int nodes_cnt; + } local_node_desc; + + } node_nlri; + + struct link_nlri { + + struct { + /** type of the local node descriptor */ + uint16_t type; + + /** Length of local node descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_link_state_node_descriptor_t *nodes; + + /** Allocated length of nodes */ + int _nodes_alloc_cnt; + + /** Populated length of nodes */ + int nodes_cnt; + } local_node_desc; + + struct { + /** type of the remote node descriptor */ + uint16_t type; + + /** Length of remote node descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_link_state_node_descriptor_t *nodes; + + /** Allocated length of nodes */ + int _nodes_alloc_cnt; + + /** Populated length of nodes */ + int nodes_cnt; + } remote_node_desc; + + struct { + /** type of the link descriptor */ + uint16_t type; + + /** Length of link descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_link_state_link_descriptor_t *links; + + /** Allocated length of nodes */ + int _links_alloc_cnt; + + /** Populated length of nodes */ + int links_cnt; + } link_desc; + + } link_nlri; + + struct prefix_nlri_ipv4_ipv6 { + + struct { + /** type of the prefix descriptor */ + uint16_t type; + + /** Length of prefix descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_link_state_node_descriptor_t *nodes; + + /** Allocated length of nodes */ + int _nodes_alloc_cnt; + + /** Populated length of nodes */ + int nodes_cnt; + } local_node_desc; + + struct { + + /** type of the prefix descriptor */ + uint16_t type; + + /** Length of prefix descriptor (len = variable) */ + uint16_t len; + + /** Array of node descriptors */ + parsebgp_bgp_update_mp_link_state_prefix_descriptor_t *pref; + + /** Allocated length of nodes */ + int _pref_alloc_cnt; + + /** Populated length of nodes */ + int pref_cnt; + } prefix_desc; + + } prefix_nlri; + + } nlri_ls; + +} parsebgp_bgp_update_mp_link_state_t; + /** * MP_REACH_NLRI */ @@ -66,6 +322,20 @@ typedef struct parsebgp_bgp_update_mp_reach { /** (Inferred) number of NLRIs */ int nlris_cnt; + struct mp_ls { + + /** MP LS NLRI information */ + parsebgp_bgp_update_mp_link_state_t *mp_ls; + + /** Number of allocated NLRIs (INTERNAL) */ + int _mp_ls_alloc_cnt; + + /** (Inferred) number of NLRIs */ + int mp_ls_cnt; + + }mp_ls; + + } parsebgp_bgp_update_mp_reach_t; /** @@ -88,6 +358,19 @@ typedef struct parsebgp_bgp_update_mp_unreach { /** (Inferred) number of Withdrawn NLRIs */ int withdrawn_nlris_cnt; + struct mp_ls { + + /** MP LS NLRI information */ + parsebgp_bgp_update_mp_link_state_t *mp_ls; + + /** Number of allocated NLRIs (INTERNAL) */ + int _mp_ls_alloc_cnt; + + /** (Inferred) number of NLRIs */ + int mp_ls_cnt; + + }mp_ls; + } parsebgp_bgp_update_mp_unreach_t; /** Decode an MP_REACH message */ diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.h b/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.h deleted file mode 100644 index 292253c..0000000 --- a/lib/bgp/parsebgp_bgp_update_mp_reach_link_state.h +++ /dev/null @@ -1,412 +0,0 @@ -#ifndef __PARSEBGP_BGP_UPDATE_MP_MP_REACH_LINK_STATE_H -#define __PARSEBGP_BGP_UPDATE_MP_MP_REACH_LINK_STATE_H - -#include "parsebgp_bgp_common.h" -#include "parsebgp_error.h" -#include "parsebgp_opts.h" -#include "../parsebgp_opts.h" -#include "parsebgp_bgp_update_mp_reach.h" -#include "../parsebgp_error.h" -#include -#include - -/** - * Defines the BGP link state NLRI types - * https://tools.ietf.org/html/draft-ietf-idr-ls-distribution-10#section-3.2 - */ -typedef enum { - - /** NLRI TYPE: NODE NLRI */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_NODE = 1, - - /** NLRI TYPE: LINK NLRI */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_LINK = 2, - - /** NLRI TYPE: IPV4 PREFIX NLRI */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_IPV4_PREFIX = 3, - - /** NLRI TYPE: IPV^ PREFIX NLRI */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_TYPE_IPV6_PREFIX = 4 - -} parsebgp_bgp_update_mp_reach_link_state_nlri_types_t; - -/** - * TODO: check if this is required - * Defines the NLRI protocol-id values - */ -typedef enum { - - /** NLRI information source protocol: IS-IS Level 1 */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_ISIS_L1 = 1, - - /** NLRI information source protocol: IS-IS Level 2 */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_ISIS_L2 = 2, - - /** NLRI information source protocol: OSPFv2 */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_OSPFV2 = 3, - - /** NLRI information source protocol: DIRECT */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_DIRECT = 4, - - /** NLRI information source protocol: Static configuration */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_STATIC = 5, - - /** NLRI information source protocol: OSPFv3 */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NLRI_PROTO_OSPFV3 = 6, - -} parsebgp_bgp_update_mp_reach_link_state_protocol_ids_t; - -typedef enum { - - /** Routing Universe: Default Layer 3 Routing topology */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_DEF_LAYER_3_ROUTING_TOPOLOGY = 0, - -} parsebgp_bgp_update_mp_reach_link_state_identifier_t; - -/** - * Node descriptor Sub-TLV's - * Used by both remote and local node descriptors - */ -typedef enum { - //TODO: check this field - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_LOCAL_DESCR = - 256, ///< Local node descriptor - //TODO: check this field - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_REMOTE_DESCR = - 257, ///< Remote node descriptor - - /** Node Descriptor: Autonomous System (len = 4) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_AS = 512, - - /** Node Descriptor: BGP LS Identifier (len = 4) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_BGP_LS_ID = 513, - - /** Node Descriptor: OSPF Area ID (len = 4) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_OSPF_AREA_ID = 514, - - /** Node Descriptor: IGP Router ID (len = variable) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID = 515, - - //TODO: check this field - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_NODE_DESCR_BGP_ROUTER_ID = 516 ///< BGP Router ID - ///< (draft-ietf-idr-bgpls-segment-routing-epe) -} parsebgp_bgp_update_mp_reach_link_state_node_descr_sub_types_t; - -/** - * Link Descriptor Sub-TLV's - */ -typedef enum { - - /** Link Descriptor: Link Local/Remote Identifiers 22/4 (rfc5307/1.1) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_ID = 258, - - /** Link Descriptor: IPv4 interface address 22/6 (rfc5305/3.2) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV4_INTF_ADDR = 259, - - /** Link Descriptor: IPv4 neighbor address 22/8 (rfc5305/3.3) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV4_NEI_ADDR = 260, - - /** Link Descriptor: IPv4 interface address 22/6 (rfc5305/3.2) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV6_INTF_ADDR = 261, - - /** Link Descriptor: IPv6 neighbor address 22/13 (rfc6119/4.3) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_IPV6_NEI_ADDR = 262, - - /** Link Descriptor: Multi-Topology Identifier */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_LINK_DESCR_MT_ID = 263 - -} parsebgp_bgp_update_mp_reach_link_state_link_descr_sub_types_t; - -/** - * Prefix Descriptor Sub-TLV's - */ -typedef enum prefix_descr_sub_types { - - /** Prefix Descriptor: Multi-Topology Identifier (len = variable) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_MT_ID = 263, - - /** Prefix Descriptor: OSPF Route Type (len=1) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_OSPF_ROUTE_TYPE = 264, - - /** Prefix Descriptor: IP Reachability Information (len=variable) */ - PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO = 265 - -} parsebgp_bgp_update_mp_reach_link_state_prefix_descr_sub_types_t; - -/** - * OSPF Route Types - */ -//TODO: Not sure if this is required -typedef enum ospf_route_types { - OSPF_RT_INTRA_AREA = 1, ///< Intra-Area - OSPF_RT_INTER_AREA, ///< Inter-Area - OSPF_RT_EXTERNAL_1, ///< External type 1 - OSPF_RT_EXTERNAL_2, ///< External type 2 - OSPF_RT_NSSA_1, ///< NSSA type 1 - OSPF_RT_NSSA_2 ///< NSSA type 2 -}; - -/** - * Node (local and remote) common fields - */ -typedef struct parsebgp_bgp_update_mp_reach_link_state_node_descriptor { - - /** Type of the node descriptor */ - uint16_t type; - - /** Length of the node descriptor */ - uint16_t len; - - union { - /** Node Descriptor: Autonomous System (len = 4) */ - uint32_t asn; - - /** Node Descriptor: BGP LS Identifier (len = 4) */ - uint32_t bgp_ls_id; - - /** Node Descriptor: OSPF Area ID (len = 4) */ - uint32_t ospf_area_Id; - - /** Node Descriptor: IGP Router ID (len = variable) */ - uint8_t igp_router_id[8]; - - } node_value; -} parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t; - -/** - * Link Descriptor common fields - */ -typedef struct parsebgp_bgp_update_mp_reach_link_state_link_descriptor { - - /** Type of the link descriptor */ - uint16_t type; - - /** Length of the link descriptor */ - uint16_t len; - - struct { - /** Link Local ID */ - uint32_t link_local_id; - - /** Link Remote ID */ - uint32_t link_remote_id; ///< Link Remote ID - } link_ids; - - /** ipv4 Interface binary address */ - uint8_t link_ipv4_intf_addr[4]; - - /** ipv4 Neighbor binary address */ - uint8_t link_ipv4_neigh_addr[4]; - - /** ipv6 Interface binary address */ - uint8_t link_ipv6_intf_addr[16]; - - /** ipv6 Neighbor binary address */ - uint8_t link_ipv6_neigh_addr[16]; - - /** Multi-Topology ID (len=variable) */ - struct { - - /** Array of mt_ids */ - uint16_t *ids; - - /** Allocated length of ids */ - int _ids_alloc_cnt; - - /** Populated ids count */ - int ids_cnt; - - } link_mt_id; - -} parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t; - -/** - * Prefix descriptor common fields - */ -typedef struct parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor { - - /** Type of the prefix descriptor */ - uint16_t type; - - /** Length of the prefix descriptor */ - uint16_t len; - - /** Multi-Topology ID (len=variable) */ - struct { - - /** Array of mt_ids */ - uint16_t *ids; - - /** Allocated length of ids */ - int _ids_alloc_cnt; - - /** Populated ids count */ - int ids_cnt; - - } prefix_mt_id; - - /** OSPF Route type */ - uint8_t prefix_ospf_route_type; - - struct { - uint8_t prefix_len; - - /** Array of ip_prefix */ - uint8_t *ip_prefix; - - /** Allocated length of ip_prefix */ - int _ip_prefix_cnt; - - /** Populated ip_prefix count */ - int ip_prefix_cnt; - - }prefix_ip_reach_info; - -} parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor_t; - -typedef struct parsebgp_bgp_update_mp_reach_link_state { - - /** AFI : 16388, SAFI : 71 */ - - /** Type of NLRI: node, link, ipv4 prefix, ipv6 prefix */ - uint16_t nlri_type; - - /** Length of the rest of the NLRI excluding type and itslef */ - uint16_t nlri_len; - - /** Contains NLRI information source protocol */ - uint8_t protocol_id; - - /** Identifier has info of Routing Universe */ - uint64_t identifier; - - struct nlri_ls { - - struct node_nlri { - - /** type of the node descriptor */ - uint16_t type; - - /** Length of node descriptor (len = variable) */ - uint16_t len; - - struct { - /** Array of node descriptors */ - parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *nodes; - - /** Allocated length of nodes */ - int _nodes_alloc_cnt; - - /** Populated length of nodes */ - int nodes_cnt; - } local_node_desc; - - } node_nlri; - - struct link_nlri { - - struct { - /** type of the local node descriptor */ - uint16_t type; - - /** Length of local node descriptor (len = variable) */ - uint16_t len; - - /** Array of node descriptors */ - parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *nodes; - - /** Allocated length of nodes */ - int _nodes_alloc_cnt; - - /** Populated length of nodes */ - int nodes_cnt; - } local_node_desc; - - struct { - /** type of the remote node descriptor */ - uint16_t type; - - /** Length of remote node descriptor (len = variable) */ - uint16_t len; - - /** Array of node descriptors */ - parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *nodes; - - /** Allocated length of nodes */ - int _nodes_alloc_cnt; - - /** Populated length of nodes */ - int nodes_cnt; - } remote_node_desc; - - struct { - /** type of the link descriptor */ - uint16_t type; - - /** Length of link descriptor (len = variable) */ - uint16_t len; - - /** Array of node descriptors */ - parsebgp_bgp_update_mp_reach_link_state_link_descriptor_t *links; - - /** Allocated length of nodes */ - int _links_alloc_cnt; - - /** Populated length of nodes */ - int links_cnt; - } link_desc; - - } link_nlri; - - struct prefix_nlri_ipv4_ipv6 { - - struct { - /** type of the prefix descriptor */ - uint16_t type; - - /** Length of prefix descriptor (len = variable) */ - uint16_t len; - - /** Array of node descriptors */ - parsebgp_bgp_update_mp_reach_link_state_node_descriptor_t *nodes; - - /** Allocated length of nodes */ - int _nodes_alloc_cnt; - - /** Populated length of nodes */ - int nodes_cnt; - } local_node_desc; - - struct { - - /** type of the prefix descriptor */ - uint16_t type; - - /** Length of prefix descriptor (len = variable) */ - uint16_t len; - - /** Array of node descriptors */ - parsebgp_bgp_update_mp_reach_link_state_prefix_descriptor_t *pref; - - /** Allocated length of nodes */ - int _pref_alloc_cnt; - - /** Populated length of nodes */ - int pref_cnt; - } prefix_desc; - - } prefix_nlri; - - } nlri_ls; - -} parsebgp_bgp_update_mp_reach_link_state_t; - -/** Decode an MP_REACH message */ -parsebgp_error_t -parsebgp_bgp_update_mp_reach_link_state_decode(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_reach_t *msg, - uint8_t *buf, - size_t *lenp, - size_t remain); - -#endif __PARSEBGP_BGP_UPDATE_MP_REACH_LINK_STATE_H \ No newline at end of file From 95d526d53a00cc719a3378cd014d8f56b3acc988 Mon Sep 17 00:00:00 2001 From: Ojas Gupta Date: Mon, 27 Nov 2017 19:28:22 -0800 Subject: [PATCH 3/7] Added dump function in link state --- lib/bgp/parsebgp_bgp_update_mp_link_state.c | 559 +++++++++++++++++--- lib/bgp/parsebgp_bgp_update_mp_link_state.h | 31 ++ lib/bgp/parsebgp_bgp_update_mp_reach.c | 33 +- lib/bgp/parsebgp_bgp_update_mp_reach.h | 5 +- 4 files changed, 561 insertions(+), 67 deletions(-) diff --git a/lib/bgp/parsebgp_bgp_update_mp_link_state.c b/lib/bgp/parsebgp_bgp_update_mp_link_state.c index d0c2429..aeed852 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_link_state.c +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.c @@ -1,10 +1,27 @@ /* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (C) 2017 The Regents of the University of California. * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "parsebgp_bgp_update_mp_link_state.h" #include "parsebgp_bgp_update_mp_reach.h" @@ -35,8 +52,8 @@ parse_link_state_nlri_node_val(parsebgp_opts_t *opts, switch (node->type) { case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: - if (node->len != sizeof(node->node_value.asn)){ - PARSEBGP_RETURN_INVALID_MSG_ERR; + if (node->len != sizeof(node->node_value.asn)) { + PARSEBGP_RETURN_INVALID_MSG_ERR; } PARSEBGP_DESERIALIZE_VAL(buf, len, nread, node->node_value.asn); @@ -44,7 +61,7 @@ parse_link_state_nlri_node_val(parsebgp_opts_t *opts, break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: - if (node->len != sizeof(node->node_value.bgp_ls_id)){ + if (node->len != sizeof(node->node_value.bgp_ls_id)) { PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -53,7 +70,7 @@ parse_link_state_nlri_node_val(parsebgp_opts_t *opts, break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: - if (node->len != sizeof(node->node_value.ospf_area_Id)){ + if (node->len != sizeof(node->node_value.ospf_area_Id)) { PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -106,14 +123,15 @@ parse_link_state_nlri_node(parsebgp_opts_t *opts, parsebgp_bgp_update_mp_link_state_node_descriptor_t *node; - while(nread < msg->nlri_ls.node_nlri.len) { + while (nread < msg->nlri_ls.node_nlri.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.node_nlri.local_node_desc.nodes, sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.node_nlri.local_node_desc._nodes_alloc_cnt, msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt + 1); - node = &msg->nlri_ls.node_nlri.local_node_desc.nodes[msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt]; + node = + &msg->nlri_ls.node_nlri.local_node_desc.nodes[msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt]; msg->nlri_ls.node_nlri.local_node_desc.nodes_cnt += 1; slen = len - nread; @@ -152,7 +170,7 @@ parse_link_state_nlri_link_val(parsebgp_opts_t *opts, case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_ID: - if (link->len != 8){ + if (link->len != 8) { PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -165,7 +183,7 @@ parse_link_state_nlri_link_val(parsebgp_opts_t *opts, break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_INTF_ADDR: - if (link->len != 4){ + if (link->len != 4) { PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -173,7 +191,7 @@ parse_link_state_nlri_link_val(parsebgp_opts_t *opts, break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_NEI_ADDR: - if (link->len != 4){ + if (link->len != 4) { PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -181,7 +199,7 @@ parse_link_state_nlri_link_val(parsebgp_opts_t *opts, break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_INTF_ADDR: - if (link->len != 16){ + if (link->len != 16) { PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -189,7 +207,7 @@ parse_link_state_nlri_link_val(parsebgp_opts_t *opts, break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_NEI_ADDR: - if (link->len != 16){ + if (link->len != 16) { PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -243,25 +261,34 @@ parse_link_state_nlri_link(parsebgp_opts_t *opts, parsebgp_error_t err; // Read the node type - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.local_node_desc.type); - msg->nlri_ls.link_nlri.local_node_desc.type = ntohs(msg->nlri_ls.link_nlri.local_node_desc.type); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.link_nlri.local_node_desc.type); + msg->nlri_ls.link_nlri.local_node_desc.type = + ntohs(msg->nlri_ls.link_nlri.local_node_desc.type); // Read the node length - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.local_node_desc.len); - msg->nlri_ls.link_nlri.local_node_desc.len = ntohs(msg->nlri_ls.link_nlri.local_node_desc.len); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.link_nlri.local_node_desc.len); + msg->nlri_ls.link_nlri.local_node_desc.len = + ntohs(msg->nlri_ls.link_nlri.local_node_desc.len); msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt = 0; parsebgp_bgp_update_mp_link_state_node_descriptor_t *node; - while(nread < msg->nlri_ls.link_nlri.local_node_desc.len) { + while (nread < msg->nlri_ls.link_nlri.local_node_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.link_nlri.local_node_desc.nodes, sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.link_nlri.local_node_desc._nodes_alloc_cnt, msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt + 1); - node = &msg->nlri_ls.link_nlri.local_node_desc.nodes[msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt]; + node = + &msg->nlri_ls.link_nlri.local_node_desc.nodes[msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt]; msg->nlri_ls.link_nlri.local_node_desc.nodes_cnt += 1; slen = len - nread; @@ -278,23 +305,32 @@ parse_link_state_nlri_link(parsebgp_opts_t *opts, // Read the node type - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.remote_node_desc.type); - msg->nlri_ls.link_nlri.remote_node_desc.type = ntohs(msg->nlri_ls.link_nlri.remote_node_desc.type); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.link_nlri.remote_node_desc.type); + msg->nlri_ls.link_nlri.remote_node_desc.type = + ntohs(msg->nlri_ls.link_nlri.remote_node_desc.type); // Read the node length - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.remote_node_desc.len); - msg->nlri_ls.link_nlri.remote_node_desc.len = ntohs(msg->nlri_ls.link_nlri.remote_node_desc.len); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.link_nlri.remote_node_desc.len); + msg->nlri_ls.link_nlri.remote_node_desc.len = + ntohs(msg->nlri_ls.link_nlri.remote_node_desc.len); msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt = 0; - while(nread < msg->nlri_ls.link_nlri.remote_node_desc.len) { + while (nread < msg->nlri_ls.link_nlri.remote_node_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.link_nlri.remote_node_desc.nodes, sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.link_nlri.remote_node_desc._nodes_alloc_cnt, msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt + 1); - node = &msg->nlri_ls.link_nlri.remote_node_desc.nodes[msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt]; + node = + &msg->nlri_ls.link_nlri.remote_node_desc.nodes[msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt]; msg->nlri_ls.link_nlri.remote_node_desc.nodes_cnt += 1; slen = len - nread; @@ -311,25 +347,34 @@ parse_link_state_nlri_link(parsebgp_opts_t *opts, // Read the node type - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.link_desc.type); - msg->nlri_ls.link_nlri.link_desc.type = ntohs(msg->nlri_ls.link_nlri.link_desc.type); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.link_nlri.link_desc.type); + msg->nlri_ls.link_nlri.link_desc.type = + ntohs(msg->nlri_ls.link_nlri.link_desc.type); // Read the node length - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.link_nlri.link_desc.len); - msg->nlri_ls.link_nlri.link_desc.len = ntohs(msg->nlri_ls.link_nlri.link_desc.len); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.link_nlri.link_desc.len); + msg->nlri_ls.link_nlri.link_desc.len = + ntohs(msg->nlri_ls.link_nlri.link_desc.len); msg->nlri_ls.link_nlri.link_desc.links_cnt = 0; parsebgp_bgp_update_mp_link_state_link_descriptor_t *link; - while(nread < msg->nlri_ls.link_nlri.link_desc.len) { + while (nread < msg->nlri_ls.link_nlri.link_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.link_nlri.link_desc.links, sizeof(parsebgp_bgp_update_mp_link_state_link_descriptor_t), msg->nlri_ls.link_nlri.link_desc._links_alloc_cnt, msg->nlri_ls.link_nlri.link_desc.links_cnt + 1); - link = &msg->nlri_ls.link_nlri.link_desc.links[msg->nlri_ls.link_nlri.link_desc.links_cnt]; + link = + &msg->nlri_ls.link_nlri.link_desc.links[msg->nlri_ls.link_nlri.link_desc.links_cnt]; msg->nlri_ls.link_nlri.link_desc.links_cnt += 1; slen = len - nread; @@ -391,7 +436,7 @@ parse_link_state_nlri_prefix_val(parsebgp_opts_t *opts, break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_OSPF_ROUTE_TYPE: - if (prefix->len != sizeof(prefix->prefix_ospf_route_type)){ + if (prefix->len != sizeof(prefix->prefix_ospf_route_type)) { PARSEBGP_RETURN_INVALID_MSG_ERR; } @@ -422,7 +467,6 @@ parse_link_state_nlri_prefix_val(parsebgp_opts_t *opts, return PARSEBGP_OK; } - static parsebgp_error_t parse_link_state_nlri_prefix(parsebgp_opts_t *opts, parsebgp_bgp_update_mp_link_state_t *msg, @@ -432,25 +476,34 @@ parse_link_state_nlri_prefix(parsebgp_opts_t *opts, parsebgp_error_t err; // Read the node type - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.prefix_nlri.local_node_desc.type); - msg->nlri_ls.prefix_nlri.local_node_desc.type = ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.type); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.prefix_nlri.local_node_desc.type); + msg->nlri_ls.prefix_nlri.local_node_desc.type = + ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.type); // Read the node length - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.prefix_nlri.local_node_desc.len); - msg->nlri_ls.prefix_nlri.local_node_desc.len = ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.len); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.prefix_nlri.local_node_desc.len); + msg->nlri_ls.prefix_nlri.local_node_desc.len = + ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.len); msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt = 0; parsebgp_bgp_update_mp_link_state_node_descriptor_t *node; - while(nread < msg->nlri_ls.prefix_nlri.local_node_desc.len) { + while (nread < msg->nlri_ls.prefix_nlri.local_node_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.prefix_nlri.local_node_desc.nodes, sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.prefix_nlri.local_node_desc._nodes_alloc_cnt, msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt + 1); - node = &msg->nlri_ls.prefix_nlri.local_node_desc.nodes[msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt]; + node = + &msg->nlri_ls.prefix_nlri.local_node_desc.nodes[msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt]; msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt += 1; slen = len - nread; @@ -466,25 +519,34 @@ parse_link_state_nlri_prefix(parsebgp_opts_t *opts, } // Read the node type - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.prefix_nlri.prefix_desc.type); - msg->nlri_ls.prefix_nlri.local_node_desc.type = ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.type); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.prefix_nlri.prefix_desc.type); + msg->nlri_ls.prefix_nlri.local_node_desc.type = + ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.type); // Read the node length - PARSEBGP_DESERIALIZE_VAL(buf, len, nread, msg->nlri_ls.prefix_nlri.local_node_desc.len); - msg->nlri_ls.prefix_nlri.local_node_desc.len = ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.len); + PARSEBGP_DESERIALIZE_VAL(buf, + len, + nread, + msg->nlri_ls.prefix_nlri.local_node_desc.len); + msg->nlri_ls.prefix_nlri.local_node_desc.len = + ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.len); msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt = 0; parsebgp_bgp_update_mp_link_state_prefix_descriptor_t *prefix; - while(nread < msg->nlri_ls.prefix_nlri.prefix_desc.len) { + while (nread < msg->nlri_ls.prefix_nlri.prefix_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.prefix_nlri.prefix_desc.pref, sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), msg->nlri_ls.prefix_nlri.prefix_desc._pref_alloc_cnt, msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt + 1); - prefix = &msg->nlri_ls.prefix_nlri.prefix_desc.pref[msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt]; + prefix = + &msg->nlri_ls.prefix_nlri.prefix_desc.pref[msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt]; msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt += 1; slen = len - nread; @@ -506,10 +568,10 @@ parse_link_state_nlri_prefix(parsebgp_opts_t *opts, static parsebgp_error_t parse_reach_link_state_nlri(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_reach_t *msg, - uint8_t *buf, - size_t *lenp, - size_t remain) { + parsebgp_bgp_update_mp_reach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain) { size_t len = *lenp, nread = 0, slen; parsebgp_error_t err; @@ -589,8 +651,12 @@ parse_reach_link_state_nlri(parsebgp_opts_t *opts, break; default: - PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, nread, remain - nread, - "Unsupported NLRI type (%d)", ls_nlri->nlri_type); + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, + buf, + nread, + remain - nread, + "Unsupported NLRI type (%d)", + ls_nlri->nlri_type); } @@ -604,10 +670,10 @@ parse_reach_link_state_nlri(parsebgp_opts_t *opts, static parsebgp_error_t parse_unreach_link_state_nlri(parsebgp_opts_t *opts, - parsebgp_bgp_update_mp_unreach_t *msg, - uint8_t *buf, - size_t *lenp, - size_t remain) { + parsebgp_bgp_update_mp_unreach_t *msg, + uint8_t *buf, + size_t *lenp, + size_t remain) { size_t len = *lenp, nread = 0, slen; parsebgp_error_t err; @@ -687,8 +753,12 @@ parse_unreach_link_state_nlri(parsebgp_opts_t *opts, break; default: - PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, nread, remain - nread, - "Unsupported NLRI type (%d)", ls_nlri->nlri_type); + PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, + buf, + nread, + remain - nread, + "Unsupported NLRI type (%d)", + ls_nlri->nlri_type); } @@ -740,6 +810,369 @@ parsebgp_bgp_update_mp_reach_link_state_decode(parsebgp_opts_t *opts, return PARSEBGP_OK; } +void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t *msg, + int depth) { + + int i, j, k; + depth++; + + parsebgp_bgp_update_mp_link_state_t *mp_ls; + + switch (msg->safi) { + case PARSEBGP_BGP_SAFI_BGPLS: + + for (i = 0; i < msg->mp_ls.mp_ls_cnt; i++) { + mp_ls = &msg->mp_ls.mp_ls[i]; + + PARSEBGP_DUMP_STRUCT_HDR(parsebgp_bgp_update_mp_link_state_t, depth); + + PARSEBGP_DUMP_INT(depth, "NLRI Type", mp_ls->nlri_type); + PARSEBGP_DUMP_INT(depth, "NLRI Length", mp_ls->nlri_len); + PARSEBGP_DUMP_INT(depth, "Protocol ID", mp_ls->protocol_id); + printf("%" PRIu64, mp_ls->identifier); + + depth++; + switch (mp_ls->nlri_type) { + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_NODE: + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_node_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, "Node Type", mp_ls->nlri_ls.node_nlri.type); + PARSEBGP_DUMP_INT(depth, "node Length", mp_ls->nlri_ls.node_nlri.len); + + parsebgp_bgp_update_mp_link_state_node_descriptor_t *node; + for (j = 0; j < mp_ls->nlri_ls.node_nlri.local_node_desc.nodes_cnt; + j++) { + node = &mp_ls->nlri_ls.node_nlri.local_node_desc.nodes[j]; + + PARSEBGP_DUMP_INT(depth, "Node Desc Type", node->type); + PARSEBGP_DUMP_INT(depth, "node Desc Length", node->len); + + depth++; + + switch (node->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: + PARSEBGP_DUMP_INT(depth, "AS Number", node->node_value.asn); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: + PARSEBGP_DUMP_INT(depth, "BGP LS ID", node->node_value.bgp_ls_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + PARSEBGP_DUMP_INT(depth, + "OSPF Area ID", + node->node_value.ospf_area_Id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + PARSEBGP_DUMP_INFO(depth, + "IGP Router ID", + node->node_value.igp_router_id); + break; + } + depth--; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_LINK: + + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_node_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Local Node Type", + mp_ls->nlri_ls.link_nlri.local_node_desc.type); + PARSEBGP_DUMP_INT(depth, + "Local Node Length", + mp_ls->nlri_ls.link_nlri.local_node_desc.len); + + parsebgp_bgp_update_mp_link_state_node_descriptor_t *link_node; + for (j = 0; j < mp_ls->nlri_ls.link_nlri.local_node_desc.nodes_cnt; + j++) { + link_node = &mp_ls->nlri_ls.link_nlri.local_node_desc.nodes[j]; + + PARSEBGP_DUMP_INT(depth, "Local node Desc Type", link_node->type); + PARSEBGP_DUMP_INT(depth, "Local node Desc Length", link_node->len); + + depth++; + + switch (link_node->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: + PARSEBGP_DUMP_INT(depth, "AS Number", link_node->node_value.asn); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: + PARSEBGP_DUMP_INT(depth, + "BGP LS ID", + link_node->node_value.bgp_ls_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + PARSEBGP_DUMP_INT(depth, + "OSPF Area ID", + link_node->node_value.ospf_area_Id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + PARSEBGP_DUMP_INFO(depth, + "IGP Router ID", + link_node->node_value.igp_router_id); + break; + } + depth--; + } + + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_node_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Remote Node Type", + mp_ls->nlri_ls.link_nlri.remote_node_desc.type); + PARSEBGP_DUMP_INT(depth, + "Remote Node Length", + mp_ls->nlri_ls.link_nlri.remote_node_desc.len); + + for (j = 0; j < mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes_cnt; + j++) { + link_node = &mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes[j]; + + PARSEBGP_DUMP_INT(depth, "Remote node Desc Type", link_node->type); + PARSEBGP_DUMP_INT(depth, "Remote node Desc Length", link_node->len); + + depth++; + + switch (link_node->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: + PARSEBGP_DUMP_INT(depth, "AS Number", link_node->node_value.asn); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: + PARSEBGP_DUMP_INT(depth, + "BGP LS ID", + link_node->node_value.bgp_ls_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + PARSEBGP_DUMP_INT(depth, + "OSPF Area ID", + link_node->node_value.ospf_area_Id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + PARSEBGP_DUMP_INFO(depth, + "IGP Router ID", + link_node->node_value.igp_router_id); + break; + } + depth--; + } + + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_link_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Link Type", + mp_ls->nlri_ls.link_nlri.link_desc.type); + PARSEBGP_DUMP_INT(depth, + "Link Length", + mp_ls->nlri_ls.link_nlri.link_desc.len); + + parsebgp_bgp_update_mp_link_state_link_descriptor_t *link; + for (j = 0; j < mp_ls->nlri_ls.link_nlri.link_desc.links_cnt; j++) { + link = &mp_ls->nlri_ls.link_nlri.link_desc.links[j]; + + PARSEBGP_DUMP_INT(depth, "Link Desc Type", link->type); + PARSEBGP_DUMP_INT(depth, "Link Desc Length", link->len); + + depth++; + + switch (link->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_ID: + PARSEBGP_DUMP_INT(depth, + "Link Local ID", + link->link_ids.link_local_id); + PARSEBGP_DUMP_INT(depth, + "Link Remote ID", + link->link_ids.link_remote_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_INTF_ADDR: + PARSEBGP_DUMP_IP(depth, + "Link ipv4 Interface address", + PARSEBGP_BGP_AFI_IPV4, + link->link_ipv4_intf_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_NEI_ADDR: + PARSEBGP_DUMP_IP(depth, + "Link ipv4 Neighbor address", + PARSEBGP_BGP_AFI_IPV4, + link->link_ipv4_neigh_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_INTF_ADDR: + PARSEBGP_DUMP_IP(depth, + "Link ipv6 Interface address", + PARSEBGP_BGP_AFI_IPV6, + link->link_ipv6_intf_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_NEI_ADDR: + PARSEBGP_DUMP_IP(depth, + "Link ipv6 Neighbor address", + PARSEBGP_BGP_AFI_IPV6, + link->link_ipv6_neigh_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_MT_ID: + + for (k = 0; k < link->link_mt_id.ids_cnt; k++) { + PARSEBGP_DUMP_INT(depth, + "Link MT ID", + link->link_mt_id.ids[k]); + } + break; + + default: + PARSEBGP_DUMP_INFO(depth, + "MP_REACH Link State Link desc type %d Not Supported\n", + link->type); + } + depth--; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV4_PREFIX: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV6_PREFIX: + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_node_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Prefix Local Node Type", + mp_ls->nlri_ls.prefix_nlri.local_node_desc.type); + PARSEBGP_DUMP_INT(depth, + "Prefix Local Node Length", + mp_ls->nlri_ls.prefix_nlri.local_node_desc.len); + + parsebgp_bgp_update_mp_link_state_node_descriptor_t *prefix_node; + for (j = 0; j < mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt; + j++) { + prefix_node = &mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes[j]; + + PARSEBGP_DUMP_INT(depth, + "Prefix Local node Desc Type", + prefix_node->type); + PARSEBGP_DUMP_INT(depth, + "Prefix Local node Desc Length", + prefix_node->len); + + depth++; + + switch (prefix_node->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: + PARSEBGP_DUMP_INT(depth, "AS Number", prefix_node->node_value.asn); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: + PARSEBGP_DUMP_INT(depth, + "BGP LS ID", + prefix_node->node_value.bgp_ls_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + PARSEBGP_DUMP_INT(depth, + "OSPF Area ID", + prefix_node->node_value.ospf_area_Id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + PARSEBGP_DUMP_INFO(depth, + "IGP Router ID", + prefix_node->node_value.igp_router_id); + break; + } + depth--; + } + + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_prefix_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Prefix Type", + mp_ls->nlri_ls.prefix_nlri.prefix_desc.type); + PARSEBGP_DUMP_INT(depth, + "Prefix Length", + mp_ls->nlri_ls.prefix_nlri.prefix_desc.len); + + parsebgp_bgp_update_mp_link_state_prefix_descriptor_t *prefix; + for (j = 0; j < mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref_cnt; j++) { + prefix = &mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref[j]; + + PARSEBGP_DUMP_INT(depth, "Prefix Desc Type", prefix->type); + PARSEBGP_DUMP_INT(depth, "Prefix Desc Length", prefix->len); + + depth++; + + switch (prefix->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_MT_ID: + for (k = 0; k < link->link_mt_id.ids_cnt; k++) { + PARSEBGP_DUMP_INT(depth, + "Prefix MT ID", + prefix->prefix_mt_id.ids[k]); + } + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_OSPF_ROUTE_TYPE: + PARSEBGP_DUMP_INT(depth, + "Prefix PSPF Route Type", + prefix->prefix_ospf_route_type); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO: + //TODO: Ask Alistair +// PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, +// buf, +// nread, +// len, +// "Unsupported NLRI node type (%d)", +// prefix->type); + break; + + default: + PARSEBGP_DUMP_INFO(depth, + "MP_REACH Link State Prefix type %d Not Supported\n", + prefix->type); + depth--; + } + + break; + + default: + PARSEBGP_DUMP_INFO(depth, + "MP_REACH Link State NLRI type %d Not Supported\n", + mp_ls->nlri_type); + + } + depth--; + } + break; + } + + default: + PARSEBGP_DUMP_INFO(depth, "MP_REACH SAFI %d Not Supported\n", msg->safi); + break; + } +} + parsebgp_error_t parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, parsebgp_bgp_update_mp_unreach_t *msg, @@ -755,7 +1188,7 @@ parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, case PARSEBGP_BGP_SAFI_BGPLS: slen = len - nread; if ((err = parse_unreach_link_state_nlri(opts, msg, buf, &slen, - remain - nread)) != PARSEBGP_OK) { + remain - nread)) != PARSEBGP_OK) { return err; } nread += slen; @@ -772,3 +1205,9 @@ parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, return PARSEBGP_OK; } + +void parsebgp_bgp_update_mp_unreach_link_state_dump( + parsebgp_bgp_update_mp_unreach_t *msg, + int depth) { + +} \ No newline at end of file diff --git a/lib/bgp/parsebgp_bgp_update_mp_link_state.h b/lib/bgp/parsebgp_bgp_update_mp_link_state.h index 6e1998c..feedf8d 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_link_state.h +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.h @@ -1,3 +1,29 @@ +/* + * Copyright (C) 2017 The Regents of the University of California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + #ifndef __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H #define __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H @@ -114,6 +140,8 @@ parsebgp_bgp_update_mp_reach_link_state_decode(parsebgp_opts_t *opts, uint8_t *buf, size_t *lenp, size_t remain); +void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t *msg, + int depth); /** Decode an MP_REACH message */ parsebgp_error_t @@ -123,4 +151,7 @@ parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, size_t *lenp, size_t remain); +void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unreach_t *msg, + int depth); + #endif __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H \ No newline at end of file diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach.c b/lib/bgp/parsebgp_bgp_update_mp_reach.c index 3dea941..b7f2a95 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_reach.c +++ b/lib/bgp/parsebgp_bgp_update_mp_reach.c @@ -161,7 +161,7 @@ parse_next_hop_afi_ipv4_ipv6(parsebgp_bgp_update_mp_reach_t *msg, uint8_t *buf, } static parsebgp_error_t -parse_reach_afi_ipv4_ipv6(parsebgp_opts_t *opts, + parse_reach_afi_ipv4_ipv6(parsebgp_opts_t *opts, parsebgp_bgp_update_mp_reach_t *msg, uint8_t *buf, size_t *lenp, size_t remain) { @@ -337,13 +337,22 @@ void parsebgp_bgp_update_mp_reach_destroy(parsebgp_bgp_update_mp_reach_t *msg) return; } - free(msg->nlris); + if(msg->nlris) { + free(msg->nlris); + } + + if(msg->mp_ls.mp_ls){ + free(msg->mp_ls.mp_ls); + } + free(msg); } void parsebgp_bgp_update_mp_reach_clear(parsebgp_bgp_update_mp_reach_t *msg) { msg->nlris_cnt = 0; + msg->mp_ls.mp_ls_cnt = 0; + } void parsebgp_bgp_update_mp_reach_dump(parsebgp_bgp_update_mp_reach_t *msg, @@ -356,7 +365,8 @@ void parsebgp_bgp_update_mp_reach_dump(parsebgp_bgp_update_mp_reach_t *msg, PARSEBGP_DUMP_INT(depth, "Next Hop Length", msg->next_hop_len); if (msg->safi != PARSEBGP_BGP_SAFI_UNICAST && - msg->safi != PARSEBGP_BGP_SAFI_MULTICAST) { + msg->safi != PARSEBGP_BGP_SAFI_MULTICAST && + msg->safi != PARSEBGP_BGP_SAFI_BGPLS) { PARSEBGP_DUMP_INFO(depth, "MP_REACH SAFI %d Not Supported\n", msg->safi); return; } @@ -376,6 +386,11 @@ void parsebgp_bgp_update_mp_reach_dump(parsebgp_bgp_update_mp_reach_t *msg, parsebgp_bgp_dump_prefixes(msg->nlris, msg->nlris_cnt, depth + 1); break; + case PARSEBGP_BGP_AFI_BGPLS: + PARSEBGP_DUMP_IP(depth, "Next Hop", msg->afi, msg->next_hop); + parsebgp_bgp_update_mp_reach_link_state_dump(msg, depth); + break; + default: PARSEBGP_DUMP_INFO(depth, "MP_REACH AFI %d Not Supported\n", msg->afi); break; @@ -449,13 +464,20 @@ void parsebgp_bgp_update_mp_unreach_destroy( if (msg == NULL) { return; } - free(msg->withdrawn_nlris); + if(msg->withdrawn_nlris) { + free(msg->withdrawn_nlris); + } + + if(msg->mp_ls.mp_ls){ + free(msg->mp_ls.mp_ls); + } free(msg); } void parsebgp_bgp_update_mp_unreach_clear(parsebgp_bgp_update_mp_unreach_t *msg) { msg->withdrawn_nlris_cnt = 0; + msg->mp_ls.mp_ls_cnt = 0; } void parsebgp_bgp_update_mp_unreach_dump(parsebgp_bgp_update_mp_unreach_t *msg, @@ -480,6 +502,9 @@ void parsebgp_bgp_update_mp_unreach_dump(parsebgp_bgp_update_mp_unreach_t *msg, parsebgp_bgp_dump_prefixes(msg->withdrawn_nlris, msg->withdrawn_nlris_cnt, depth + 1); break; + case PARSEBGP_BGP_AFI_BGPLS: + parsebgp_bgp_update_mp_unreach_link_state_dump(msg,depth); + break; default: PARSEBGP_DUMP_INFO(depth, "MP_UNREACH AFI %d Not Supported\n", msg->afi); diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach.h b/lib/bgp/parsebgp_bgp_update_mp_reach.h index 4c813a5..f21623e 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_reach.h +++ b/lib/bgp/parsebgp_bgp_update_mp_reach.h @@ -28,7 +28,6 @@ #define __PARSEBGP_BGP_UPDATE_MP_REACH_H #include "parsebgp_bgp_common.h" -//#include "parsebgp_bgp_update_mp_link_state.h" #include "parsebgp_error.h" #include "parsebgp_opts.h" #include @@ -322,7 +321,7 @@ typedef struct parsebgp_bgp_update_mp_reach { /** (Inferred) number of NLRIs */ int nlris_cnt; - struct mp_ls { + struct mp_reach_ls { /** MP LS NLRI information */ parsebgp_bgp_update_mp_link_state_t *mp_ls; @@ -358,7 +357,7 @@ typedef struct parsebgp_bgp_update_mp_unreach { /** (Inferred) number of Withdrawn NLRIs */ int withdrawn_nlris_cnt; - struct mp_ls { + struct mp_unreach_ls { /** MP LS NLRI information */ parsebgp_bgp_update_mp_link_state_t *mp_ls; From 9d28dbd63fdf9a0dd3ef5d95ac903c95050d4b1f Mon Sep 17 00:00:00 2001 From: Ojas Gupta Date: Tue, 28 Nov 2017 12:30:00 -0800 Subject: [PATCH 4/7] Updated Clear, destroy methods in MP Link State Parsing --- lib/bgp/parsebgp_bgp_update_mp_link_state.c | 507 +++++++++++++++++++- lib/bgp/parsebgp_bgp_update_mp_link_state.h | 13 + lib/bgp/parsebgp_bgp_update_mp_reach.c | 5 +- 3 files changed, 514 insertions(+), 11 deletions(-) diff --git a/lib/bgp/parsebgp_bgp_update_mp_link_state.c b/lib/bgp/parsebgp_bgp_update_mp_link_state.c index aeed852..3705ba6 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_link_state.c +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.c @@ -1138,13 +1138,8 @@ void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO: - //TODO: Ask Alistair -// PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, -// buf, -// nread, -// len, -// "Unsupported NLRI node type (%d)", -// prefix->type); + ARSEBGP_DUMP_INFO(depth, + "MP_REACH Link State IP_REACH_INFO No implemented\n"); break; default: @@ -1173,6 +1168,74 @@ void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t } } +void parsebgp_bgp_update_mp_reach_link_state_destroy( + parsebgp_bgp_update_mp_reach_t *msg) +{ + int i, j; + parsebgp_bgp_update_mp_link_state_t *mp_ls; + + for (i = 0; i < msg->mp_ls._mp_ls_alloc_cnt; i++) { + mp_ls = &msg->mp_ls.mp_ls[i]; + + if(mp_ls->nlri_ls.node_nlri.local_node_desc.nodes){ + free(mp_ls->nlri_ls.node_nlri.local_node_desc.nodes); + } + + if(mp_ls->nlri_ls.link_nlri.local_node_desc.nodes){ + free(mp_ls->nlri_ls.link_nlri.local_node_desc.nodes); + } + + if(mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes){ + free(mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes); + } + + if(mp_ls->nlri_ls.link_nlri.link_desc.links){ + for (j = 0; j < mp_ls->nlri_ls.link_nlri.link_desc._links_alloc_cnt; j++) { + if(mp_ls->nlri_ls.link_nlri.link_desc.links->link_mt_id.ids) { + free(mp_ls->nlri_ls.link_nlri.link_desc.links->link_mt_id.ids); + } + } + free(mp_ls->nlri_ls.link_nlri.link_desc.links); + } + + if(mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes){ + free(mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes); + } + + if(mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref){ + for (j = 0; j < mp_ls->nlri_ls.prefix_nlri.prefix_desc._pref_alloc_cnt; j++) { + if(mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref->prefix_mt_id.ids) { + free(mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref->prefix_mt_id.ids); + } + } + free(mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref); + } + } +} + +void parsebgp_bgp_update_mp_reach_link_state_clear( + parsebgp_bgp_update_mp_reach_t *msg) +{ + int i; + parsebgp_bgp_update_mp_link_state_t *mp_ls; + + for (i = 0; i < msg->mp_ls.mp_ls_cnt; i++) { + mp_ls = &msg->mp_ls.mp_ls[i]; + + mp_ls->nlri_ls.node_nlri.local_node_desc.nodes_cnt = 0; + + mp_ls->nlri_ls.link_nlri.local_node_desc.nodes_cnt = 0; + + mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes_cnt = 0; + + mp_ls->nlri_ls.link_nlri.link_desc.links_cnt = 0; + + mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt = 0; + + mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref_cnt = 0; + } +} + parsebgp_error_t parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, parsebgp_bgp_update_mp_unreach_t *msg, @@ -1206,8 +1269,432 @@ parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, } -void parsebgp_bgp_update_mp_unreach_link_state_dump( - parsebgp_bgp_update_mp_unreach_t *msg, - int depth) { +void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unreach_t *msg, + int depth) { + + int i, j, k; + depth++; + + parsebgp_bgp_update_mp_link_state_t *mp_ls; + + switch (msg->safi) { + case PARSEBGP_BGP_SAFI_BGPLS: + + for (i = 0; i < msg->mp_ls.mp_ls_cnt; i++) { + mp_ls = &msg->mp_ls.mp_ls[i]; + + PARSEBGP_DUMP_STRUCT_HDR(parsebgp_bgp_update_mp_link_state_t, depth); + + PARSEBGP_DUMP_INT(depth, "NLRI Type", mp_ls->nlri_type); + PARSEBGP_DUMP_INT(depth, "NLRI Length", mp_ls->nlri_len); + PARSEBGP_DUMP_INT(depth, "Protocol ID", mp_ls->protocol_id); + printf("%" PRIu64, mp_ls->identifier); + + depth++; + switch (mp_ls->nlri_type) { + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_NODE: + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_node_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, "Node Type", mp_ls->nlri_ls.node_nlri.type); + PARSEBGP_DUMP_INT(depth, "node Length", mp_ls->nlri_ls.node_nlri.len); + + parsebgp_bgp_update_mp_link_state_node_descriptor_t *node; + for (j = 0; j < mp_ls->nlri_ls.node_nlri.local_node_desc.nodes_cnt; + j++) { + node = &mp_ls->nlri_ls.node_nlri.local_node_desc.nodes[j]; + + PARSEBGP_DUMP_INT(depth, "Node Desc Type", node->type); + PARSEBGP_DUMP_INT(depth, "node Desc Length", node->len); + + depth++; + + switch (node->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: + PARSEBGP_DUMP_INT(depth, "AS Number", node->node_value.asn); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: + PARSEBGP_DUMP_INT(depth, "BGP LS ID", node->node_value.bgp_ls_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + PARSEBGP_DUMP_INT(depth, + "OSPF Area ID", + node->node_value.ospf_area_Id); + break; + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + PARSEBGP_DUMP_INFO(depth, + "IGP Router ID", + node->node_value.igp_router_id); + break; + } + depth--; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_LINK: + + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_node_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Local Node Type", + mp_ls->nlri_ls.link_nlri.local_node_desc.type); + PARSEBGP_DUMP_INT(depth, + "Local Node Length", + mp_ls->nlri_ls.link_nlri.local_node_desc.len); + + parsebgp_bgp_update_mp_link_state_node_descriptor_t *link_node; + for (j = 0; j < mp_ls->nlri_ls.link_nlri.local_node_desc.nodes_cnt; + j++) { + link_node = &mp_ls->nlri_ls.link_nlri.local_node_desc.nodes[j]; + + PARSEBGP_DUMP_INT(depth, "Local node Desc Type", link_node->type); + PARSEBGP_DUMP_INT(depth, "Local node Desc Length", link_node->len); + + depth++; + + switch (link_node->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: + PARSEBGP_DUMP_INT(depth, "AS Number", link_node->node_value.asn); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: + PARSEBGP_DUMP_INT(depth, + "BGP LS ID", + link_node->node_value.bgp_ls_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + PARSEBGP_DUMP_INT(depth, + "OSPF Area ID", + link_node->node_value.ospf_area_Id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + PARSEBGP_DUMP_INFO(depth, + "IGP Router ID", + link_node->node_value.igp_router_id); + break; + } + depth--; + } + + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_node_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Remote Node Type", + mp_ls->nlri_ls.link_nlri.remote_node_desc.type); + PARSEBGP_DUMP_INT(depth, + "Remote Node Length", + mp_ls->nlri_ls.link_nlri.remote_node_desc.len); + + for (j = 0; j < mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes_cnt; + j++) { + link_node = &mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes[j]; + + PARSEBGP_DUMP_INT(depth, "Remote node Desc Type", link_node->type); + PARSEBGP_DUMP_INT(depth, "Remote node Desc Length", link_node->len); + + depth++; + + switch (link_node->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: + PARSEBGP_DUMP_INT(depth, "AS Number", link_node->node_value.asn); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: + PARSEBGP_DUMP_INT(depth, + "BGP LS ID", + link_node->node_value.bgp_ls_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + PARSEBGP_DUMP_INT(depth, + "OSPF Area ID", + link_node->node_value.ospf_area_Id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + PARSEBGP_DUMP_INFO(depth, + "IGP Router ID", + link_node->node_value.igp_router_id); + break; + } + depth--; + } + + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_link_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Link Type", + mp_ls->nlri_ls.link_nlri.link_desc.type); + PARSEBGP_DUMP_INT(depth, + "Link Length", + mp_ls->nlri_ls.link_nlri.link_desc.len); + + parsebgp_bgp_update_mp_link_state_link_descriptor_t *link; + for (j = 0; j < mp_ls->nlri_ls.link_nlri.link_desc.links_cnt; j++) { + link = &mp_ls->nlri_ls.link_nlri.link_desc.links[j]; + + PARSEBGP_DUMP_INT(depth, "Link Desc Type", link->type); + PARSEBGP_DUMP_INT(depth, "Link Desc Length", link->len); + + depth++; + + switch (link->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_ID: + PARSEBGP_DUMP_INT(depth, + "Link Local ID", + link->link_ids.link_local_id); + PARSEBGP_DUMP_INT(depth, + "Link Remote ID", + link->link_ids.link_remote_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_INTF_ADDR: + PARSEBGP_DUMP_IP(depth, + "Link ipv4 Interface address", + PARSEBGP_BGP_AFI_IPV4, + link->link_ipv4_intf_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV4_NEI_ADDR: + PARSEBGP_DUMP_IP(depth, + "Link ipv4 Neighbor address", + PARSEBGP_BGP_AFI_IPV4, + link->link_ipv4_neigh_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_INTF_ADDR: + PARSEBGP_DUMP_IP(depth, + "Link ipv6 Interface address", + PARSEBGP_BGP_AFI_IPV6, + link->link_ipv6_intf_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_IPV6_NEI_ADDR: + PARSEBGP_DUMP_IP(depth, + "Link ipv6 Neighbor address", + PARSEBGP_BGP_AFI_IPV6, + link->link_ipv6_neigh_addr); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_LINK_DESCR_MT_ID: + + for (k = 0; k < link->link_mt_id.ids_cnt; k++) { + PARSEBGP_DUMP_INT(depth, + "Link MT ID", + link->link_mt_id.ids[k]); + } + break; + + default: + PARSEBGP_DUMP_INFO(depth, + "MP_REACH Link State Link desc type %d Not Supported\n", + link->type); + } + depth--; + } + + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV4_PREFIX: + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NLRI_TYPE_IPV6_PREFIX: + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_node_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Prefix Local Node Type", + mp_ls->nlri_ls.prefix_nlri.local_node_desc.type); + PARSEBGP_DUMP_INT(depth, + "Prefix Local Node Length", + mp_ls->nlri_ls.prefix_nlri.local_node_desc.len); + + parsebgp_bgp_update_mp_link_state_node_descriptor_t *prefix_node; + for (j = 0; j < mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt; + j++) { + prefix_node = &mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes[j]; + + PARSEBGP_DUMP_INT(depth, + "Prefix Local node Desc Type", + prefix_node->type); + PARSEBGP_DUMP_INT(depth, + "Prefix Local node Desc Length", + prefix_node->len); + + depth++; + + switch (prefix_node->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_AS: + PARSEBGP_DUMP_INT(depth, "AS Number", prefix_node->node_value.asn); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_BGP_LS_ID: + PARSEBGP_DUMP_INT(depth, + "BGP LS ID", + prefix_node->node_value.bgp_ls_id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_OSPF_AREA_ID: + PARSEBGP_DUMP_INT(depth, + "OSPF Area ID", + prefix_node->node_value.ospf_area_Id); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: + PARSEBGP_DUMP_INFO(depth, + "IGP Router ID", + prefix_node->node_value.igp_router_id); + break; + } + depth--; + } + + PARSEBGP_DUMP_STRUCT_HDR( + parsebgp_bgp_update_mp_link_state_prefix_descriptor_t, + depth); + PARSEBGP_DUMP_INT(depth, + "Prefix Type", + mp_ls->nlri_ls.prefix_nlri.prefix_desc.type); + PARSEBGP_DUMP_INT(depth, + "Prefix Length", + mp_ls->nlri_ls.prefix_nlri.prefix_desc.len); + + parsebgp_bgp_update_mp_link_state_prefix_descriptor_t *prefix; + for (j = 0; j < mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref_cnt; j++) { + prefix = &mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref[j]; + + PARSEBGP_DUMP_INT(depth, "Prefix Desc Type", prefix->type); + PARSEBGP_DUMP_INT(depth, "Prefix Desc Length", prefix->len); + + depth++; + + switch (prefix->type) { + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_MT_ID: + for (k = 0; k < link->link_mt_id.ids_cnt; k++) { + PARSEBGP_DUMP_INT(depth, + "Prefix MT ID", + prefix->prefix_mt_id.ids[k]); + } + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_OSPF_ROUTE_TYPE: + PARSEBGP_DUMP_INT(depth, + "Prefix PSPF Route Type", + prefix->prefix_ospf_route_type); + break; + + case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO: + //TODO: Ask Alistair +// PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, +// buf, +// nread, +// len, +// "Unsupported NLRI node type (%d)", +// prefix->type); + break; + + default: + PARSEBGP_DUMP_INFO(depth, + "MP_REACH Link State Prefix type %d Not Supported\n", + prefix->type); + depth--; + } + + break; + + default: + PARSEBGP_DUMP_INFO(depth, + "MP_REACH Link State NLRI type %d Not Supported\n", + mp_ls->nlri_type); + + } + depth--; + } + break; + } + + default: + PARSEBGP_DUMP_INFO(depth, "MP_REACH SAFI %d Not Supported\n", msg->safi); + break; + } +} + +void parsebgp_bgp_update_mp_unreach_destroy( + parsebgp_bgp_update_mp_unreach_t *msg) +{ + int i, j; + parsebgp_bgp_update_mp_link_state_t *mp_ls; + + for (i = 0; i < msg->mp_ls.mp_ls_cnt; i++) { + mp_ls = &msg->mp_ls.mp_ls[i]; + + if(mp_ls->nlri_ls.node_nlri.local_node_desc.nodes){ + free(mp_ls->nlri_ls.node_nlri.local_node_desc.nodes); + } + + if(mp_ls->nlri_ls.link_nlri.local_node_desc.nodes){ + free(mp_ls->nlri_ls.link_nlri.local_node_desc.nodes); + } + + if(mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes){ + free(mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes); + } + + if(mp_ls->nlri_ls.link_nlri.link_desc.links){ + for (j = 0; j < mp_ls->nlri_ls.link_nlri.link_desc.links_cnt; j++) { + if(mp_ls->nlri_ls.link_nlri.link_desc.links->link_mt_id.ids) { + free(mp_ls->nlri_ls.link_nlri.link_desc.links->link_mt_id.ids); + } + } + free(mp_ls->nlri_ls.link_nlri.link_desc.links); + } + + if(mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes){ + free(mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes); + } + + if(mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref){ + for (j = 0; j < mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref_cnt; j++) { + if(mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref->prefix_mt_id.ids) { + free(mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref->prefix_mt_id.ids); + } + } + free(mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref); + } + } +} + +void parsebgp_bgp_update_mp_unreach_link_state_clear(parsebgp_bgp_update_mp_unreach_t *msg) +{ + int i; + parsebgp_bgp_update_mp_link_state_t *mp_ls; + + for (i = 0; i < msg->mp_ls.mp_ls_cnt; i++) { + mp_ls = &msg->mp_ls.mp_ls[i]; + + mp_ls->nlri_ls.node_nlri.local_node_desc.nodes_cnt = 0; + + mp_ls->nlri_ls.link_nlri.local_node_desc.nodes_cnt = 0; + + mp_ls->nlri_ls.link_nlri.remote_node_desc.nodes_cnt = 0; + + mp_ls->nlri_ls.link_nlri.link_desc.links_cnt = 0; + + mp_ls->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt = 0; + + mp_ls->nlri_ls.prefix_nlri.prefix_desc.pref_cnt = 0; + } } \ No newline at end of file diff --git a/lib/bgp/parsebgp_bgp_update_mp_link_state.h b/lib/bgp/parsebgp_bgp_update_mp_link_state.h index feedf8d..5b7ed34 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_link_state.h +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.h @@ -140,9 +140,16 @@ parsebgp_bgp_update_mp_reach_link_state_decode(parsebgp_opts_t *opts, uint8_t *buf, size_t *lenp, size_t remain); + void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t *msg, int depth); +void parsebgp_bgp_update_mp_reach_link_state_destroy( + parsebgp_bgp_update_mp_reach_t *msg); + +void parsebgp_bgp_update_mp_reach_link_state_clear( + parsebgp_bgp_update_mp_reach_t *msg); + /** Decode an MP_REACH message */ parsebgp_error_t parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, @@ -154,4 +161,10 @@ parsebgp_bgp_update_mp_unreach_link_state_decode(parsebgp_opts_t *opts, void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unreach_t *msg, int depth); +void parsebgp_bgp_update_mp_unreach_link_state_destroy( + parsebgp_bgp_update_mp_unreach_t *msg); + +void parsebgp_bgp_update_mp_unreach_link_state_clear( + parsebgp_bgp_update_mp_unreach_t *msg); + #endif __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H \ No newline at end of file diff --git a/lib/bgp/parsebgp_bgp_update_mp_reach.c b/lib/bgp/parsebgp_bgp_update_mp_reach.c index b7f2a95..39334f3 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_reach.c +++ b/lib/bgp/parsebgp_bgp_update_mp_reach.c @@ -342,6 +342,7 @@ void parsebgp_bgp_update_mp_reach_destroy(parsebgp_bgp_update_mp_reach_t *msg) } if(msg->mp_ls.mp_ls){ + parsebgp_bgp_update_mp_reach_link_state_destroy(msg); free(msg->mp_ls.mp_ls); } @@ -351,8 +352,8 @@ void parsebgp_bgp_update_mp_reach_destroy(parsebgp_bgp_update_mp_reach_t *msg) void parsebgp_bgp_update_mp_reach_clear(parsebgp_bgp_update_mp_reach_t *msg) { msg->nlris_cnt = 0; + parsebgp_bgp_update_mp_reach_link_state_clear(msg); msg->mp_ls.mp_ls_cnt = 0; - } void parsebgp_bgp_update_mp_reach_dump(parsebgp_bgp_update_mp_reach_t *msg, @@ -469,6 +470,7 @@ void parsebgp_bgp_update_mp_unreach_destroy( } if(msg->mp_ls.mp_ls){ + parsebgp_bgp_update_mp_unreach_link_state_destroy(msg); free(msg->mp_ls.mp_ls); } free(msg); @@ -477,6 +479,7 @@ void parsebgp_bgp_update_mp_unreach_destroy( void parsebgp_bgp_update_mp_unreach_clear(parsebgp_bgp_update_mp_unreach_t *msg) { msg->withdrawn_nlris_cnt = 0; + parsebgp_bgp_update_mp_unreach_link_state_clear(msg); msg->mp_ls.mp_ls_cnt = 0; } From 8d63b8ca8d595c48a53d99b84e9893aabe7dc3f7 Mon Sep 17 00:00:00 2001 From: Ojas Gupta Date: Tue, 28 Nov 2017 12:33:12 -0800 Subject: [PATCH 5/7] Removed minor bug in MP LS Parsing --- lib/bgp/parsebgp_bgp_update_mp_link_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bgp/parsebgp_bgp_update_mp_link_state.c b/lib/bgp/parsebgp_bgp_update_mp_link_state.c index 3705ba6..3357610 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_link_state.c +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.c @@ -1632,7 +1632,7 @@ void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unrea } } -void parsebgp_bgp_update_mp_unreach_destroy( +void parsebgp_bgp_update_mp_unreach_link_state_destroy( parsebgp_bgp_update_mp_unreach_t *msg) { int i, j; From a46308969b116beabbd6d048e3077757dd1354d9 Mon Sep 17 00:00:00 2001 From: Ojas Gupta Date: Tue, 28 Nov 2017 12:40:07 -0800 Subject: [PATCH 6/7] Removed minor bug in MP LS Parsing --- lib/bgp/parsebgp_bgp_update_mp_link_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bgp/parsebgp_bgp_update_mp_link_state.c b/lib/bgp/parsebgp_bgp_update_mp_link_state.c index 3357610..1ad366f 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_link_state.c +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.c @@ -1138,7 +1138,7 @@ void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO: - ARSEBGP_DUMP_INFO(depth, + PARSEBGP_DUMP_INFO(depth, "MP_REACH Link State IP_REACH_INFO No implemented\n"); break; From 594b00118d12eebf696dc89fe7916e7dfcd87277 Mon Sep 17 00:00:00 2001 From: Ojas Gupta Date: Mon, 4 Dec 2017 12:25:57 -0800 Subject: [PATCH 7/7] Just some minor changes --- lib/bgp/parsebgp_bgp_update_mp_link_state.c | 91 +++++++++++---------- lib/bgp/parsebgp_bgp_update_mp_link_state.h | 12 +-- 2 files changed, 48 insertions(+), 55 deletions(-) diff --git a/lib/bgp/parsebgp_bgp_update_mp_link_state.c b/lib/bgp/parsebgp_bgp_update_mp_link_state.c index 1ad366f..26e14d4 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_link_state.c +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.c @@ -523,24 +523,24 @@ parse_link_state_nlri_prefix(parsebgp_opts_t *opts, len, nread, msg->nlri_ls.prefix_nlri.prefix_desc.type); - msg->nlri_ls.prefix_nlri.local_node_desc.type = - ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.type); + msg->nlri_ls.prefix_nlri.prefix_desc.type = + ntohs(msg->nlri_ls.prefix_nlri.prefix_desc.type); // Read the node length PARSEBGP_DESERIALIZE_VAL(buf, len, nread, - msg->nlri_ls.prefix_nlri.local_node_desc.len); - msg->nlri_ls.prefix_nlri.local_node_desc.len = - ntohs(msg->nlri_ls.prefix_nlri.local_node_desc.len); + msg->nlri_ls.prefix_nlri.prefix_desc.len); + msg->nlri_ls.prefix_nlri.prefix_desc.len = + ntohs(msg->nlri_ls.prefix_nlri.prefix_desc.len); - msg->nlri_ls.prefix_nlri.local_node_desc.nodes_cnt = 0; + msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt = 0; parsebgp_bgp_update_mp_link_state_prefix_descriptor_t *prefix; while (nread < msg->nlri_ls.prefix_nlri.prefix_desc.len) { PARSEBGP_MAYBE_REALLOC(msg->nlri_ls.prefix_nlri.prefix_desc.pref, - sizeof(parsebgp_bgp_update_mp_link_state_node_descriptor_t), + sizeof(parsebgp_bgp_update_mp_link_state_prefix_descriptor_t), msg->nlri_ls.prefix_nlri.prefix_desc._pref_alloc_cnt, msg->nlri_ls.prefix_nlri.prefix_desc.pref_cnt + 1); @@ -867,9 +867,9 @@ void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: - PARSEBGP_DUMP_INFO(depth, + PARSEBGP_DUMP_DATA(depth, "IGP Router ID", - node->node_value.igp_router_id); + node->node_value.igp_router_id, node->len); break; } depth--; @@ -918,9 +918,9 @@ void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: - PARSEBGP_DUMP_INFO(depth, + PARSEBGP_DUMP_DATA(depth, "IGP Router ID", - link_node->node_value.igp_router_id); + link_node->node_value.igp_router_id, link_node->len); break; } depth--; @@ -964,9 +964,9 @@ void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: - PARSEBGP_DUMP_INFO(depth, + PARSEBGP_DUMP_DATA(depth, "IGP Router ID", - link_node->node_value.igp_router_id); + link_node->node_value.igp_router_id, link_node->len); break; } depth--; @@ -1094,9 +1094,9 @@ void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: - PARSEBGP_DUMP_INFO(depth, + PARSEBGP_DUMP_DATA(depth, "IGP Router ID", - prefix_node->node_value.igp_router_id); + prefix_node->node_value.igp_router_id, prefix_node->len); break; } depth--; @@ -1124,7 +1124,7 @@ void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t switch (prefix->type) { case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_MT_ID: - for (k = 0; k < link->link_mt_id.ids_cnt; k++) { + for (k = 0; k < prefix->prefix_mt_id.ids_cnt; k++) { PARSEBGP_DUMP_INT(depth, "Prefix MT ID", prefix->prefix_mt_id.ids[k]); @@ -1138,33 +1138,36 @@ void parsebgp_bgp_update_mp_reach_link_state_dump(parsebgp_bgp_update_mp_reach_t break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_IP_REACH_INFO: - PARSEBGP_DUMP_INFO(depth, - "MP_REACH Link State IP_REACH_INFO No implemented\n"); + //TODO: Ask Alistair +// PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, +// buf, +// nread, +// len, +// "Unsupported NLRI node type (%d)", +// prefix->type); break; default: PARSEBGP_DUMP_INFO(depth, "MP_REACH Link State Prefix type %d Not Supported\n", prefix->type); - depth--; + break; } + depth--; + } - break; - - default: - PARSEBGP_DUMP_INFO(depth, - "MP_REACH Link State NLRI type %d Not Supported\n", - mp_ls->nlri_type); + default: + PARSEBGP_DUMP_INFO(depth, + "MP_REACH Link State NLRI type %d Not Supported\n", + mp_ls->nlri_type); - } - depth--; } - break; } + break; - default: - PARSEBGP_DUMP_INFO(depth, "MP_REACH SAFI %d Not Supported\n", msg->safi); - break; + default: + PARSEBGP_DUMP_INFO(depth, "MP_REACH SAFI %d Not Supported\n", msg->safi); + break; } } @@ -1326,9 +1329,9 @@ void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unrea break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: - PARSEBGP_DUMP_INFO(depth, + PARSEBGP_DUMP_DATA(depth, "IGP Router ID", - node->node_value.igp_router_id); + node->node_value.igp_router_id, node->len); break; } depth--; @@ -1377,9 +1380,9 @@ void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unrea break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: - PARSEBGP_DUMP_INFO(depth, + PARSEBGP_DUMP_DATA(depth, "IGP Router ID", - link_node->node_value.igp_router_id); + link_node->node_value.igp_router_id, link_node->len); break; } depth--; @@ -1423,9 +1426,9 @@ void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unrea break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: - PARSEBGP_DUMP_INFO(depth, + PARSEBGP_DUMP_DATA(depth, "IGP Router ID", - link_node->node_value.igp_router_id); + link_node->node_value.igp_router_id, link_node->len); break; } depth--; @@ -1553,9 +1556,9 @@ void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unrea break; case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_NODE_DESCR_IGP_ROUTER_ID: - PARSEBGP_DUMP_INFO(depth, + PARSEBGP_DUMP_DATA(depth, "IGP Router ID", - prefix_node->node_value.igp_router_id); + prefix_node->node_value.igp_router_id, prefix_node->len); break; } depth--; @@ -1583,7 +1586,7 @@ void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unrea switch (prefix->type) { case PARSEBGP_BGP_UPDATE_MP_LINK_STATE_PREFIX_DESCR_MT_ID: - for (k = 0; k < link->link_mt_id.ids_cnt; k++) { + for (k = 0; k < prefix->prefix_mt_id.ids_cnt; k++) { PARSEBGP_DUMP_INT(depth, "Prefix MT ID", prefix->prefix_mt_id.ids[k]); @@ -1610,10 +1613,10 @@ void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unrea PARSEBGP_DUMP_INFO(depth, "MP_REACH Link State Prefix type %d Not Supported\n", prefix->type); - depth--; + break; } - - break; + depth--; + } default: PARSEBGP_DUMP_INFO(depth, @@ -1621,10 +1624,8 @@ void parsebgp_bgp_update_mp_unreach_link_state_dump(parsebgp_bgp_update_mp_unrea mp_ls->nlri_type); } - depth--; } break; - } default: PARSEBGP_DUMP_INFO(depth, "MP_REACH SAFI %d Not Supported\n", msg->safi); diff --git a/lib/bgp/parsebgp_bgp_update_mp_link_state.h b/lib/bgp/parsebgp_bgp_update_mp_link_state.h index 5b7ed34..c1f2958 100644 --- a/lib/bgp/parsebgp_bgp_update_mp_link_state.h +++ b/lib/bgp/parsebgp_bgp_update_mp_link_state.h @@ -28,9 +28,9 @@ #define __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H #include "parsebgp_bgp_common.h" +#include "parsebgp_bgp_update_mp_reach.h" #include "parsebgp_error.h" #include "parsebgp_opts.h" -#include "parsebgp_bgp_update_mp_reach.h" #include #include @@ -54,14 +54,6 @@ typedef enum { } parsebgp_bgp_update_mp_link_state_nlri_types_t; - -typedef enum { - - /** Routing Universe: Default Layer 3 Routing topology */ - PARSEBGP_BGP_UPDATE_MP_LINK_STATE_DEF_LAYER_3_ROUTING_TOPOLOGY = 0, - -} parsebgp_bgp_update_mp_link_state_identifier_t; - /** * Node descriptor Sub-TLV's * Used by both remote and local node descriptors @@ -167,4 +159,4 @@ void parsebgp_bgp_update_mp_unreach_link_state_destroy( void parsebgp_bgp_update_mp_unreach_link_state_clear( parsebgp_bgp_update_mp_unreach_t *msg); -#endif __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H \ No newline at end of file +#endif /* __PARSEBGP_BGP_UPDATE_MP_LINK_STATE_H */ \ No newline at end of file