2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2016-04-19 19:21:17 +02:00
|
|
|
/*
|
|
|
|
* This is an implementation of RFC4970 Router Information
|
|
|
|
* with support of RFC5088 PCE Capabilites announcement
|
|
|
|
*
|
|
|
|
* Module name: Router Information
|
2018-01-18 19:11:11 +01:00
|
|
|
* Author: Olivier Dugeon <olivier.dugeon@orange.com>
|
|
|
|
* Copyright (C) 2012 - 2017 Orange Labs http://www.orange.com/
|
2016-04-19 19:21:17 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "vty.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "log.h"
|
2023-03-07 20:22:48 +01:00
|
|
|
#include "frrevent.h"
|
2016-04-19 19:21:17 +02:00
|
|
|
#include "hash.h"
|
|
|
|
#include "sockunion.h" /* for inet_aton() */
|
2018-01-18 19:11:11 +01:00
|
|
|
#include "mpls.h"
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
#include "ospfd/ospfd.h"
|
|
|
|
#include "ospfd/ospf_interface.h"
|
|
|
|
#include "ospfd/ospf_ism.h"
|
|
|
|
#include "ospfd/ospf_asbr.h"
|
|
|
|
#include "ospfd/ospf_lsa.h"
|
|
|
|
#include "ospfd/ospf_lsdb.h"
|
|
|
|
#include "ospfd/ospf_neighbor.h"
|
|
|
|
#include "ospfd/ospf_nsm.h"
|
|
|
|
#include "ospfd/ospf_flood.h"
|
|
|
|
#include "ospfd/ospf_packet.h"
|
|
|
|
#include "ospfd/ospf_spf.h"
|
|
|
|
#include "ospfd/ospf_dump.h"
|
|
|
|
#include "ospfd/ospf_route.h"
|
|
|
|
#include "ospfd/ospf_ase.h"
|
|
|
|
#include "ospfd/ospf_zebra.h"
|
2018-01-18 19:11:11 +01:00
|
|
|
#include "ospfd/ospf_sr.h"
|
2016-04-19 19:21:17 +02:00
|
|
|
#include "ospfd/ospf_ri.h"
|
2018-08-21 01:47:59 +02:00
|
|
|
#include "ospfd/ospf_errors.h"
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Global variable to manage Opaque-LSA/Router Information on this node.
|
|
|
|
* Note that all parameter values are stored in network byte order.
|
|
|
|
*/
|
|
|
|
static struct ospf_router_info OspfRI;
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------------------*
|
2022-04-01 22:27:55 +02:00
|
|
|
* Following are initialize/terminate functions for Router Information
|
2016-04-19 19:21:17 +02:00
|
|
|
*handling.
|
|
|
|
*------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
static void ospf_router_info_ism_change(struct ospf_interface *oi,
|
|
|
|
int old_status);
|
|
|
|
static void ospf_router_info_config_write_router(struct vty *vty);
|
2021-10-08 02:06:01 +02:00
|
|
|
static void ospf_router_info_show_info(struct vty *vty,
|
|
|
|
struct json_object *json,
|
|
|
|
struct ospf_lsa *lsa);
|
2016-04-19 19:21:17 +02:00
|
|
|
static int ospf_router_info_lsa_originate(void *arg);
|
|
|
|
static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa);
|
2018-10-26 19:12:41 +02:00
|
|
|
static void ospf_router_info_lsa_schedule(struct ospf_ri_area_info *ai,
|
|
|
|
enum lsa_opcode opcode);
|
2016-04-19 19:21:17 +02:00
|
|
|
static void ospf_router_info_register_vty(void);
|
2018-01-18 19:11:11 +01:00
|
|
|
static int ospf_router_info_lsa_update(struct ospf_lsa *lsa);
|
2018-10-26 19:12:41 +02:00
|
|
|
static void del_area_info(void *val);
|
2016-04-19 19:21:17 +02:00
|
|
|
static void del_pce_info(void *val);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
int ospf_router_info_init(void)
|
|
|
|
{
|
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
zlog_info("RI (%s): Initialize Router Information", __func__);
|
2018-01-18 19:11:11 +01:00
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&OspfRI, 0, sizeof(OspfRI));
|
2017-07-27 16:09:00 +02:00
|
|
|
OspfRI.enabled = false;
|
2016-04-19 19:21:17 +02:00
|
|
|
OspfRI.registered = 0;
|
|
|
|
OspfRI.scope = OSPF_OPAQUE_AS_LSA;
|
2018-10-26 19:12:41 +02:00
|
|
|
OspfRI.as_flags = RIFLG_LSA_INACTIVE;
|
|
|
|
OspfRI.area_info = list_new();
|
|
|
|
OspfRI.area_info->del = del_area_info;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
/* Initialize pce domain and neighbor list */
|
2017-07-27 16:09:00 +02:00
|
|
|
OspfRI.pce_info.enabled = false;
|
2016-04-19 19:21:17 +02:00
|
|
|
OspfRI.pce_info.pce_domain = list_new();
|
|
|
|
OspfRI.pce_info.pce_domain->del = del_pce_info;
|
|
|
|
OspfRI.pce_info.pce_neighbor = list_new();
|
|
|
|
OspfRI.pce_info.pce_neighbor->del = del_pce_info;
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Initialize Segment Routing information structure */
|
|
|
|
OspfRI.sr_info.enabled = false;
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
ospf_router_info_register_vty();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static int ospf_router_info_register(uint8_t scope)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
int rc = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (OspfRI.registered)
|
2017-07-20 19:57:43 +02:00
|
|
|
return rc;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
zlog_info("RI (%s): Register Router Information with scope %s(%d)",
|
|
|
|
__func__,
|
2016-04-19 19:21:17 +02:00
|
|
|
scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS", scope);
|
|
|
|
rc = ospf_register_opaque_functab(
|
|
|
|
scope, OPAQUE_TYPE_ROUTER_INFORMATION_LSA,
|
|
|
|
NULL, /* new interface */
|
|
|
|
NULL, /* del interface */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_ism_change,
|
|
|
|
NULL, /* NSM change */
|
2016-04-19 19:21:17 +02:00
|
|
|
ospf_router_info_config_write_router,
|
|
|
|
NULL, /* Config. write interface */
|
|
|
|
NULL, /* Config. write debug */
|
2018-01-18 19:11:11 +01:00
|
|
|
ospf_router_info_show_info, ospf_router_info_lsa_originate,
|
|
|
|
ospf_router_info_lsa_refresh, ospf_router_info_lsa_update,
|
|
|
|
NULL); /* del_lsa_hook */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (rc != 0) {
|
2018-08-24 18:26:43 +02:00
|
|
|
flog_warn(
|
2018-09-13 20:56:04 +02:00
|
|
|
EC_OSPF_OPAQUE_REGISTRATION,
|
2018-10-26 19:12:41 +02:00
|
|
|
"RI (%s): Failed to register functions", __func__);
|
2016-04-19 19:21:17 +02:00
|
|
|
return rc;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
OspfRI.registered = 1;
|
|
|
|
OspfRI.scope = scope;
|
2017-07-20 19:57:43 +02:00
|
|
|
return rc;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
2019-01-24 10:12:36 +01:00
|
|
|
static int ospf_router_info_unregister(void)
|
2018-02-03 19:30:33 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
if ((OspfRI.scope != OSPF_OPAQUE_AS_LSA)
|
|
|
|
&& (OspfRI.scope != OSPF_OPAQUE_AREA_LSA)) {
|
2018-08-24 18:26:43 +02:00
|
|
|
assert("Unable to unregister Router Info functions: Wrong scope!"
|
|
|
|
== NULL);
|
2018-02-03 19:30:33 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ospf_delete_opaque_functab(OspfRI.scope,
|
|
|
|
OPAQUE_TYPE_ROUTER_INFORMATION_LSA);
|
|
|
|
|
|
|
|
OspfRI.registered = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
void ospf_router_info_term(void)
|
|
|
|
{
|
|
|
|
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&OspfRI.pce_info.pce_domain);
|
|
|
|
list_delete(&OspfRI.pce_info.pce_neighbor);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2017-07-27 16:09:00 +02:00
|
|
|
OspfRI.enabled = false;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2018-02-03 19:30:33 +01:00
|
|
|
ospf_router_info_unregister();
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-02-03 19:30:33 +01:00
|
|
|
void ospf_router_info_finish(void)
|
|
|
|
{
|
2020-05-15 19:18:36 +02:00
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct ospf_ri_area_info *ai;
|
|
|
|
|
|
|
|
/* Flush Router Info LSA */
|
|
|
|
for (ALL_LIST_ELEMENTS(OspfRI.area_info, node, nnode, ai))
|
|
|
|
if (CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED))
|
|
|
|
ospf_router_info_lsa_schedule(ai, FLUSH_THIS_LSA);
|
|
|
|
|
2018-02-03 19:30:33 +01:00
|
|
|
list_delete_all_node(OspfRI.pce_info.pce_domain);
|
|
|
|
list_delete_all_node(OspfRI.pce_info.pce_neighbor);
|
|
|
|
|
|
|
|
OspfRI.enabled = false;
|
|
|
|
}
|
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
static void del_area_info(void *val)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_OSPF_ROUTER_INFO, val);
|
|
|
|
}
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
static void del_pce_info(void *val)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_OSPF_PCE_PARAMS, val);
|
|
|
|
}
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Catch RI LSA flooding Scope for ospf_ext.[h,c] code */
|
|
|
|
struct scope_info ospf_router_info_get_flooding_scope(void)
|
|
|
|
{
|
|
|
|
struct scope_info flooding_scope;
|
2018-01-29 17:58:53 +01:00
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
|
|
|
|
flooding_scope.scope = OSPF_OPAQUE_AS_LSA;
|
2018-10-26 19:12:41 +02:00
|
|
|
flooding_scope.areas = NULL;
|
2018-01-18 19:11:11 +01:00
|
|
|
return flooding_scope;
|
|
|
|
}
|
|
|
|
flooding_scope.scope = OSPF_OPAQUE_AREA_LSA;
|
2018-10-26 19:12:41 +02:00
|
|
|
flooding_scope.areas = OspfRI.area_info;
|
2018-01-18 19:11:11 +01:00
|
|
|
return flooding_scope;
|
|
|
|
}
|
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
static struct ospf_ri_area_info *lookup_by_area(struct ospf_area *area)
|
|
|
|
{
|
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct ospf_ri_area_info *ai;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS(OspfRI.area_info, node, nnode, ai))
|
|
|
|
if (ai->area == area)
|
|
|
|
return ai;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/*------------------------------------------------------------------------*
|
2022-04-01 22:27:55 +02:00
|
|
|
* Following are control functions for ROUTER INFORMATION parameters
|
2016-04-19 19:21:17 +02:00
|
|
|
*management.
|
|
|
|
*------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
static void set_router_info_capabilities(struct ri_tlv_router_cap *ric,
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t cap)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
ric->header.type = htons(RI_TLV_CAPABILITIES);
|
|
|
|
ric->header.length = htons(RI_TLV_LENGTH);
|
|
|
|
ric->value = htonl(cap);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int set_pce_header(struct ospf_pce_info *pce)
|
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t length = 0;
|
2016-04-19 19:21:17 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct ri_pce_subtlv_domain *domain;
|
|
|
|
struct ri_pce_subtlv_neighbor *neighbor;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* PCE Address */
|
|
|
|
if (ntohs(pce->pce_address.header.type) != 0)
|
2017-07-20 19:57:43 +02:00
|
|
|
length += TLV_SIZE(&pce->pce_address.header);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* PCE Path Scope */
|
|
|
|
if (ntohs(pce->pce_scope.header.type) != 0)
|
2017-07-20 19:57:43 +02:00
|
|
|
length += TLV_SIZE(&pce->pce_scope.header);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* PCE Domain */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
|
|
|
|
if (ntohs(domain->header.type) != 0)
|
2017-07-20 19:57:43 +02:00
|
|
|
length += TLV_SIZE(&domain->header);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* PCE Neighbor */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
|
|
|
|
if (ntohs(neighbor->header.type) != 0)
|
2017-07-20 19:57:43 +02:00
|
|
|
length += TLV_SIZE(&neighbor->header);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* PCE Capabilities */
|
|
|
|
if (ntohs(pce->pce_cap_flag.header.type) != 0)
|
2017-07-20 19:57:43 +02:00
|
|
|
length += TLV_SIZE(&pce->pce_cap_flag.header);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (length != 0) {
|
|
|
|
pce->pce_header.header.type = htons(RI_TLV_PCE);
|
|
|
|
pce->pce_header.header.length = htons(length);
|
2017-07-27 16:09:00 +02:00
|
|
|
pce->enabled = true;
|
2016-04-19 19:21:17 +02:00
|
|
|
} else {
|
|
|
|
pce->pce_header.header.type = 0;
|
|
|
|
pce->pce_header.header.length = 0;
|
2017-07-27 16:09:00 +02:00
|
|
|
pce->enabled = false;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_pce_address(struct in_addr ipv4, struct ospf_pce_info *pce)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Enable PCE Info */
|
|
|
|
pce->pce_header.header.type = htons(RI_TLV_PCE);
|
|
|
|
/* Set PCE Address */
|
|
|
|
pce->pce_address.header.type = htons(RI_PCE_SUBTLV_ADDRESS);
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
pce->pce_address.header.length = htons(PCE_ADDRESS_IPV4_SIZE);
|
|
|
|
pce->pce_address.address.type = htons(PCE_ADDRESS_IPV4);
|
2016-04-19 19:21:17 +02:00
|
|
|
pce->pce_address.address.value = ipv4;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void set_pce_path_scope(uint32_t scope, struct ospf_pce_info *pce)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
/* Set PCE Scope */
|
|
|
|
pce->pce_scope.header.type = htons(RI_PCE_SUBTLV_PATH_SCOPE);
|
|
|
|
pce->pce_scope.header.length = htons(RI_TLV_LENGTH);
|
|
|
|
pce->pce_scope.value = htonl(scope);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void set_pce_domain(uint16_t type, uint32_t domain,
|
2016-04-19 19:21:17 +02:00
|
|
|
struct ospf_pce_info *pce)
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ri_pce_subtlv_domain *new;
|
|
|
|
|
|
|
|
/* Create new domain info */
|
|
|
|
new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
|
|
|
|
sizeof(struct ri_pce_subtlv_domain));
|
|
|
|
|
|
|
|
new->header.type = htons(RI_PCE_SUBTLV_DOMAIN);
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
new->header.length = htons(PCE_ADDRESS_IPV4_SIZE);
|
2016-04-19 19:21:17 +02:00
|
|
|
new->type = htons(type);
|
|
|
|
new->value = htonl(domain);
|
|
|
|
|
|
|
|
/* Add new domain to the list */
|
|
|
|
listnode_add(pce->pce_domain, new);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void unset_pce_domain(uint16_t type, uint32_t domain,
|
2016-04-19 19:21:17 +02:00
|
|
|
struct ospf_pce_info *pce)
|
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct ri_pce_subtlv_domain *old = NULL;
|
|
|
|
int found = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Search the corresponding node */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, old)) {
|
|
|
|
if ((old->type == htons(type))
|
|
|
|
&& (old->value == htonl(domain))) {
|
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* if found remove it */
|
|
|
|
if (found) {
|
|
|
|
listnode_delete(pce->pce_domain, old);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Finally free the old domain */
|
|
|
|
XFREE(MTYPE_OSPF_PCE_PARAMS, old);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void set_pce_neighbor(uint16_t type, uint32_t domain,
|
2016-04-19 19:21:17 +02:00
|
|
|
struct ospf_pce_info *pce)
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ri_pce_subtlv_neighbor *new;
|
|
|
|
|
|
|
|
/* Create new neighbor info */
|
|
|
|
new = XCALLOC(MTYPE_OSPF_PCE_PARAMS,
|
|
|
|
sizeof(struct ri_pce_subtlv_neighbor));
|
|
|
|
|
|
|
|
new->header.type = htons(RI_PCE_SUBTLV_NEIGHBOR);
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
new->header.length = htons(PCE_ADDRESS_IPV4_SIZE);
|
2016-04-19 19:21:17 +02:00
|
|
|
new->type = htons(type);
|
|
|
|
new->value = htonl(domain);
|
|
|
|
|
|
|
|
/* Add new domain to the list */
|
|
|
|
listnode_add(pce->pce_neighbor, new);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void unset_pce_neighbor(uint16_t type, uint32_t domain,
|
2016-04-19 19:21:17 +02:00
|
|
|
struct ospf_pce_info *pce)
|
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct ri_pce_subtlv_neighbor *old = NULL;
|
|
|
|
int found = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Search the corresponding node */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, old)) {
|
|
|
|
if ((old->type == htons(type))
|
|
|
|
&& (old->value == htonl(domain))) {
|
|
|
|
found = 1;
|
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* if found remove it */
|
|
|
|
if (found) {
|
|
|
|
listnode_delete(pce->pce_neighbor, old);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Finally free the old domain */
|
|
|
|
XFREE(MTYPE_OSPF_PCE_PARAMS, old);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void set_pce_cap_flag(uint32_t cap, struct ospf_pce_info *pce)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
/* Set PCE Capabilities flag */
|
|
|
|
pce->pce_cap_flag.header.type = htons(RI_PCE_SUBTLV_CAP_FLAG);
|
|
|
|
pce->pce_cap_flag.header.length = htons(RI_TLV_LENGTH);
|
|
|
|
pce->pce_cap_flag.value = htonl(cap);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Segment Routing TLV setter */
|
|
|
|
|
|
|
|
/* Algorithm SubTLV - section 3.1 */
|
2018-01-23 12:19:50 +01:00
|
|
|
static void set_sr_algorithm(uint8_t algo)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
OspfRI.sr_info.algo.value[0] = algo;
|
|
|
|
for (int i = 1; i < ALGORITHM_COUNT; i++)
|
|
|
|
OspfRI.sr_info.algo.value[i] = SR_ALGORITHM_UNSET;
|
|
|
|
|
|
|
|
/* Set TLV type and length == only 1 Algorithm */
|
|
|
|
TLV_TYPE(OspfRI.sr_info.algo) = htons(RI_SR_TLV_SR_ALGORITHM);
|
2018-01-23 12:19:50 +01:00
|
|
|
TLV_LEN(OspfRI.sr_info.algo) = htons(sizeof(uint8_t));
|
2018-01-18 19:11:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* unset Aglogithm SubTLV */
|
2018-01-23 12:19:50 +01:00
|
|
|
static void unset_sr_algorithm(uint8_t algo)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
for (int i = 0; i < ALGORITHM_COUNT; i++)
|
|
|
|
OspfRI.sr_info.algo.value[i] = SR_ALGORITHM_UNSET;
|
|
|
|
|
|
|
|
/* Unset TLV type and length */
|
|
|
|
TLV_TYPE(OspfRI.sr_info.algo) = htons(0);
|
|
|
|
TLV_LEN(OspfRI.sr_info.algo) = htons(0);
|
|
|
|
}
|
|
|
|
|
2020-06-18 19:46:28 +02:00
|
|
|
/* Set Segment Routing Global Block SubTLV - section 3.2 */
|
|
|
|
static void set_sr_global_label_range(struct sr_block srgb)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
|
|
|
/* Set Header */
|
2020-06-18 19:46:28 +02:00
|
|
|
TLV_TYPE(OspfRI.sr_info.srgb) = htons(RI_SR_TLV_SRGB_LABEL_RANGE);
|
2021-05-18 17:25:14 +02:00
|
|
|
TLV_LEN(OspfRI.sr_info.srgb) = htons(RI_SR_TLV_LABEL_RANGE_SIZE);
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Set Range Size */
|
2020-06-18 19:46:28 +02:00
|
|
|
OspfRI.sr_info.srgb.size = htonl(SET_RANGE_SIZE(srgb.range_size));
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Set Lower bound label SubTLV */
|
2020-06-18 19:46:28 +02:00
|
|
|
TLV_TYPE(OspfRI.sr_info.srgb.lower) = htons(SUBTLV_SID_LABEL);
|
|
|
|
TLV_LEN(OspfRI.sr_info.srgb.lower) = htons(SID_RANGE_LABEL_LENGTH);
|
|
|
|
OspfRI.sr_info.srgb.lower.value = htonl(SET_LABEL(srgb.lower_bound));
|
2018-01-18 19:11:11 +01:00
|
|
|
}
|
|
|
|
|
2020-06-18 19:46:28 +02:00
|
|
|
/* Unset Segment Routing Global Block SubTLV */
|
|
|
|
static void unset_sr_global_label_range(void)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
2020-06-18 19:46:28 +02:00
|
|
|
TLV_TYPE(OspfRI.sr_info.srgb) = htons(0);
|
|
|
|
TLV_LEN(OspfRI.sr_info.srgb) = htons(0);
|
|
|
|
TLV_TYPE(OspfRI.sr_info.srgb.lower) = htons(0);
|
|
|
|
TLV_LEN(OspfRI.sr_info.srgb.lower) = htons(0);
|
|
|
|
}
|
2018-01-18 19:11:11 +01:00
|
|
|
|
2020-06-18 19:46:28 +02:00
|
|
|
/* Set Segment Routing Local Block SubTLV - section 3.2 */
|
|
|
|
static void set_sr_local_label_range(struct sr_block srlb)
|
|
|
|
{
|
|
|
|
/* Set Header */
|
|
|
|
TLV_TYPE(OspfRI.sr_info.srlb) = htons(RI_SR_TLV_SRLB_LABEL_RANGE);
|
2021-05-18 17:25:14 +02:00
|
|
|
TLV_LEN(OspfRI.sr_info.srlb) = htons(RI_SR_TLV_LABEL_RANGE_SIZE);
|
2020-06-18 19:46:28 +02:00
|
|
|
/* Set Range Size */
|
|
|
|
OspfRI.sr_info.srlb.size = htonl(SET_RANGE_SIZE(srlb.range_size));
|
|
|
|
/* Set Lower bound label SubTLV */
|
|
|
|
TLV_TYPE(OspfRI.sr_info.srlb.lower) = htons(SUBTLV_SID_LABEL);
|
|
|
|
TLV_LEN(OspfRI.sr_info.srlb.lower) = htons(SID_RANGE_LABEL_LENGTH);
|
|
|
|
OspfRI.sr_info.srlb.lower.value = htonl(SET_LABEL(srlb.lower_bound));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unset Segment Routing Local Block SubTLV */
|
|
|
|
static void unset_sr_local_label_range(void)
|
|
|
|
{
|
|
|
|
TLV_TYPE(OspfRI.sr_info.srlb) = htons(0);
|
|
|
|
TLV_LEN(OspfRI.sr_info.srlb) = htons(0);
|
|
|
|
TLV_TYPE(OspfRI.sr_info.srlb.lower) = htons(0);
|
|
|
|
TLV_LEN(OspfRI.sr_info.srlb.lower) = htons(0);
|
2018-01-18 19:11:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set Maximum Stack Depth for this router */
|
2018-01-23 12:19:50 +01:00
|
|
|
static void set_sr_node_msd(uint8_t msd)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
|
|
|
TLV_TYPE(OspfRI.sr_info.msd) = htons(RI_SR_TLV_NODE_MSD);
|
2018-01-23 12:19:50 +01:00
|
|
|
TLV_LEN(OspfRI.sr_info.msd) = htons(sizeof(uint32_t));
|
2018-01-18 19:11:11 +01:00
|
|
|
OspfRI.sr_info.msd.value = msd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unset this router MSD */
|
2018-01-29 17:58:53 +01:00
|
|
|
static void unset_sr_node_msd(void)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
|
|
|
TLV_TYPE(OspfRI.sr_info.msd) = htons(0);
|
|
|
|
TLV_LEN(OspfRI.sr_info.msd) = htons(0);
|
|
|
|
}
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2018-06-14 19:19:44 +02:00
|
|
|
static void unset_param(void *tlv_buffer)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
2018-06-14 19:19:44 +02:00
|
|
|
struct tlv_header *tlv = (struct tlv_header *)tlv_buffer;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
tlv->type = 0;
|
|
|
|
/* Fill the Value to 0 */
|
2018-06-14 19:19:44 +02:00
|
|
|
memset(TLV_DATA(tlv_buffer), 0, TLV_BODY_SIZE(tlv));
|
2016-04-19 19:21:17 +02:00
|
|
|
tlv->length = 0;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void initialize_params(struct ospf_router_info *ori)
|
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t cap = 0;
|
2016-04-19 19:21:17 +02:00
|
|
|
struct ospf *top;
|
2018-10-26 19:12:41 +02:00
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct ospf_area *area;
|
|
|
|
struct ospf_ri_area_info *new;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/*
|
|
|
|
* Initialize default Router Information Capabilities.
|
|
|
|
*/
|
2017-07-20 19:57:43 +02:00
|
|
|
cap = RI_TE_SUPPORT;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
set_router_info_capabilities(&ori->router_cap, cap);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* If Area address is not null and exist, retrieve corresponding
|
|
|
|
* structure */
|
2017-08-25 22:51:12 +02:00
|
|
|
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
2018-10-26 19:12:41 +02:00
|
|
|
zlog_info("RI (%s): Initialize Router Info for %s scope", __func__,
|
|
|
|
OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Try to get available Area's context from ospf at this step.
|
|
|
|
* Do it latter if not available */
|
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
|
2020-05-15 19:18:36 +02:00
|
|
|
if (!list_isempty(OspfRI.area_info))
|
|
|
|
list_delete_all_node(OspfRI.area_info);
|
2018-10-26 19:12:41 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(top->areas, node, nnode, area)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("RI (%s): Add area %pI4 to Router Information",
|
|
|
|
__func__, &area->area_id);
|
2018-10-26 19:12:41 +02:00
|
|
|
new = XCALLOC(MTYPE_OSPF_ROUTER_INFO,
|
|
|
|
sizeof(struct ospf_ri_area_info));
|
|
|
|
new->area = area;
|
|
|
|
new->flags = RIFLG_LSA_INACTIVE;
|
|
|
|
listnode_add(OspfRI.area_info, new);
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/*
|
|
|
|
* Initialize default PCE Information values
|
|
|
|
*/
|
|
|
|
/* PCE address == OSPF Router ID */
|
|
|
|
set_pce_address(top->router_id, &ori->pce_info);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* PCE scope */
|
|
|
|
cap = 7; /* Set L, R and Rd bits to one = intra & inter-area path
|
|
|
|
computation */
|
|
|
|
set_pce_path_scope(cap, &ori->pce_info);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* PCE Capabilities */
|
|
|
|
cap = PCE_CAP_BIDIRECTIONAL | PCE_CAP_DIVERSE_PATH | PCE_CAP_OBJECTIVES
|
|
|
|
| PCE_CAP_ADDITIVE | PCE_CAP_MULTIPLE_REQ;
|
|
|
|
set_pce_cap_flag(cap, &ori->pce_info);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-26 17:27:16 +02:00
|
|
|
static int is_mandated_params_set(struct ospf_router_info *ori)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
int rc = 0;
|
|
|
|
|
2020-08-26 17:27:16 +02:00
|
|
|
if (ori == NULL)
|
2017-07-20 19:57:43 +02:00
|
|
|
return rc;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2020-08-26 17:27:16 +02:00
|
|
|
if (ntohs(ori->router_cap.header.type) == 0)
|
2017-07-20 19:57:43 +02:00
|
|
|
return rc;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2020-08-26 17:27:16 +02:00
|
|
|
if ((ntohs(ori->pce_info.pce_header.header.type) == RI_TLV_PCE)
|
|
|
|
&& (ntohs(ori->pce_info.pce_address.header.type) == 0)
|
|
|
|
&& (ntohs(ori->pce_info.pce_cap_flag.header.type) == 0))
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
if ((ori->sr_info.enabled) && (ntohs(TLV_TYPE(ori->sr_info.algo)) == 0)
|
|
|
|
&& (ntohs(TLV_TYPE(ori->sr_info.srgb)) == 0))
|
2018-01-18 19:11:11 +01:00
|
|
|
return rc;
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
rc = 1;
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
/*
|
|
|
|
* Used by Segment Routing to set new TLVs and Sub-TLVs values
|
|
|
|
*
|
|
|
|
* @param enable To activate or not Segment Routing router Information flooding
|
2020-06-18 19:46:28 +02:00
|
|
|
* @param srn Self Segment Routing node
|
2018-01-18 19:11:11 +01:00
|
|
|
*
|
|
|
|
* @return none
|
|
|
|
*/
|
2020-06-18 19:46:28 +02:00
|
|
|
void ospf_router_info_update_sr(bool enable, struct sr_node *srn)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
2018-10-26 19:12:41 +02:00
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct ospf_ri_area_info *ai;
|
|
|
|
|
|
|
|
/* First, check if Router Information is registered or not */
|
|
|
|
if (!OspfRI.registered)
|
|
|
|
ospf_router_info_register(OSPF_OPAQUE_AREA_LSA);
|
|
|
|
|
|
|
|
/* Verify that scope is AREA */
|
|
|
|
if (OspfRI.scope != OSPF_OPAQUE_AREA_LSA) {
|
|
|
|
zlog_err(
|
|
|
|
"RI (%s): Router Info is %s flooding: Change scope to Area flooding for Segment Routing",
|
|
|
|
__func__,
|
|
|
|
OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area" : "AS");
|
|
|
|
return;
|
|
|
|
}
|
2018-01-18 19:11:11 +01:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Then, activate and initialize Router Information if necessary */
|
2018-01-18 19:11:11 +01:00
|
|
|
if (!OspfRI.enabled) {
|
|
|
|
OspfRI.enabled = true;
|
|
|
|
initialize_params(&OspfRI);
|
|
|
|
}
|
|
|
|
|
2020-08-26 17:27:16 +02:00
|
|
|
/* Check that SR node is valid */
|
|
|
|
if (srn == NULL)
|
|
|
|
return;
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
if (IS_DEBUG_OSPF_SR)
|
2018-10-26 19:12:41 +02:00
|
|
|
zlog_debug("RI (%s): %s Routing Information for Segment Routing",
|
|
|
|
__func__, enable ? "Enable" : "Disable");
|
2018-01-18 19:11:11 +01:00
|
|
|
|
|
|
|
/* Unset or Set SR parameters */
|
|
|
|
if (!enable) {
|
|
|
|
unset_sr_algorithm(SR_ALGORITHM_SPF);
|
2020-06-18 19:46:28 +02:00
|
|
|
unset_sr_global_label_range();
|
|
|
|
unset_sr_local_label_range();
|
2018-01-18 19:11:11 +01:00
|
|
|
unset_sr_node_msd();
|
|
|
|
OspfRI.sr_info.enabled = false;
|
|
|
|
} else {
|
|
|
|
// Only SR_ALGORITHM_SPF is supported
|
|
|
|
set_sr_algorithm(SR_ALGORITHM_SPF);
|
2020-06-18 19:46:28 +02:00
|
|
|
set_sr_global_label_range(srn->srgb);
|
|
|
|
set_sr_local_label_range(srn->srlb);
|
|
|
|
if (srn->msd != 0)
|
|
|
|
set_sr_node_msd(srn->msd);
|
2018-01-18 19:11:11 +01:00
|
|
|
else
|
|
|
|
unset_sr_node_msd();
|
|
|
|
OspfRI.sr_info.enabled = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Refresh if already engaged or originate RI LSA */
|
2018-10-26 19:12:41 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(OspfRI.area_info, node, nnode, ai)) {
|
|
|
|
if (CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED))
|
|
|
|
ospf_router_info_lsa_schedule(ai, REFRESH_THIS_LSA);
|
|
|
|
else
|
|
|
|
ospf_router_info_lsa_schedule(ai,
|
|
|
|
REORIGINATE_THIS_LSA);
|
|
|
|
|
|
|
|
}
|
2018-01-18 19:11:11 +01:00
|
|
|
}
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/*------------------------------------------------------------------------*
|
2022-04-01 22:27:55 +02:00
|
|
|
* Following are callback functions against generic Opaque-LSAs handling.
|
2016-04-19 19:21:17 +02:00
|
|
|
*------------------------------------------------------------------------*/
|
|
|
|
static void ospf_router_info_ism_change(struct ospf_interface *oi,
|
|
|
|
int old_state)
|
|
|
|
{
|
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
struct ospf_ri_area_info *ai;
|
|
|
|
|
|
|
|
/* Collect area information */
|
|
|
|
ai = lookup_by_area(oi->area);
|
|
|
|
|
|
|
|
/* Check if area is not yet registered */
|
|
|
|
if (ai != NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Add this new area to the list */
|
|
|
|
ai = XCALLOC(MTYPE_OSPF_ROUTER_INFO, sizeof(struct ospf_ri_area_info));
|
|
|
|
ai->area = oi->area;
|
|
|
|
ai->flags = RIFLG_LSA_INACTIVE;
|
|
|
|
listnode_add(OspfRI.area_info, ai);
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------------*
|
2022-04-01 22:27:55 +02:00
|
|
|
* Following are OSPF protocol processing functions for ROUTER INFORMATION
|
2016-04-19 19:21:17 +02:00
|
|
|
*------------------------------------------------------------------------*/
|
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
static void build_tlv_header(struct stream *s, struct tlv_header *tlvh)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
stream_put(s, tlvh, sizeof(struct tlv_header));
|
2016-04-19 19:21:17 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
static void build_tlv(struct stream *s, struct tlv_header *tlvh)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
if (ntohs(tlvh->type) != 0) {
|
|
|
|
build_tlv_header(s, tlvh);
|
2017-07-31 18:03:00 +02:00
|
|
|
stream_put(s, TLV_DATA(tlvh), TLV_BODY_SIZE(tlvh));
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf_router_info_lsa_body_set(struct stream *s)
|
|
|
|
{
|
|
|
|
|
|
|
|
struct listnode *node;
|
|
|
|
struct ri_pce_subtlv_domain *domain;
|
|
|
|
struct ri_pce_subtlv_neighbor *neighbor;
|
|
|
|
|
|
|
|
/* Build Router Information TLV */
|
|
|
|
build_tlv(s, &OspfRI.router_cap.header);
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Build Segment Routing TLVs if enabled */
|
|
|
|
if (OspfRI.sr_info.enabled) {
|
|
|
|
/* Build Algorithm TLV */
|
|
|
|
build_tlv(s, &TLV_HDR(OspfRI.sr_info.algo));
|
|
|
|
/* Build SRGB TLV */
|
2020-06-18 19:46:28 +02:00
|
|
|
build_tlv(s, &TLV_HDR(OspfRI.sr_info.srgb));
|
|
|
|
/* Build SRLB TLV */
|
|
|
|
build_tlv(s, &TLV_HDR(OspfRI.sr_info.srlb));
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Build MSD TLV */
|
|
|
|
build_tlv(s, &TLV_HDR(OspfRI.sr_info.msd));
|
|
|
|
}
|
2017-07-20 19:57:43 +02:00
|
|
|
|
|
|
|
/* Add RI PCE TLV if it is set */
|
2017-07-27 16:09:00 +02:00
|
|
|
if (OspfRI.pce_info.enabled) {
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Compute PCE Info header first */
|
|
|
|
set_pce_header(&OspfRI.pce_info);
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Build PCE TLV */
|
|
|
|
build_tlv_header(s, &OspfRI.pce_info.pce_header.header);
|
|
|
|
|
|
|
|
/* Build PCE address sub-tlv */
|
|
|
|
build_tlv(s, &OspfRI.pce_info.pce_address.header);
|
|
|
|
|
|
|
|
/* Build PCE path scope sub-tlv */
|
|
|
|
build_tlv(s, &OspfRI.pce_info.pce_scope.header);
|
|
|
|
|
|
|
|
/* Build PCE domain sub-tlv */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(OspfRI.pce_info.pce_domain, node,
|
|
|
|
domain))
|
|
|
|
build_tlv(s, &domain->header);
|
|
|
|
|
|
|
|
/* Build PCE neighbor sub-tlv */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(OspfRI.pce_info.pce_neighbor, node,
|
|
|
|
neighbor))
|
|
|
|
build_tlv(s, &neighbor->header);
|
|
|
|
|
|
|
|
/* Build PCE cap flag sub-tlv */
|
|
|
|
build_tlv(s, &OspfRI.pce_info.pce_cap_flag.header);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create new opaque-LSA. */
|
2018-10-26 19:12:41 +02:00
|
|
|
static struct ospf_lsa *ospf_router_info_lsa_new(struct ospf_area *area)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
struct ospf *top;
|
|
|
|
struct stream *s;
|
|
|
|
struct lsa_header *lsah;
|
|
|
|
struct ospf_lsa *new = NULL;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t options, lsa_type;
|
2016-04-19 19:21:17 +02:00
|
|
|
struct in_addr lsa_id;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t tmp;
|
|
|
|
uint16_t length;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Create a stream for LSA. */
|
2018-08-20 20:05:53 +02:00
|
|
|
s = stream_new(OSPF_MAX_LSA_SIZE);
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
lsah = (struct lsa_header *)STREAM_DATA(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
options = OSPF_OPTION_E; /* Enable AS external as we flood RI with
|
|
|
|
Opaque Type 11 */
|
|
|
|
options |= OSPF_OPTION_O; /* Don't forget this :-) */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
lsa_type = OspfRI.scope;
|
|
|
|
/* LSA ID == 0 for Router Information see RFC 4970 */
|
|
|
|
tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_ROUTER_INFORMATION_LSA, 0);
|
|
|
|
lsa_id.s_addr = htonl(tmp);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Create an Opaque-LSA/ROUTER INFORMATION instance",
|
|
|
|
lsa_type, &lsa_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-25 22:51:12 +02:00
|
|
|
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Set opaque-LSA header fields. */
|
|
|
|
lsa_header_set(s, options, lsa_type, lsa_id, top->router_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Set opaque-LSA body fields. */
|
|
|
|
ospf_router_info_lsa_body_set(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Set length. */
|
|
|
|
length = stream_get_endp(s);
|
|
|
|
lsah->length = htons(length);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Now, create an OSPF LSA instance. */
|
2018-08-21 02:41:37 +02:00
|
|
|
new = ospf_lsa_new_and_data(length);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-04-07 22:48:24 +02:00
|
|
|
/* Routing Information is only supported for default VRF */
|
|
|
|
new->vrf_id = VRF_DEFAULT;
|
2018-10-26 19:12:41 +02:00
|
|
|
new->area = area;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
SET_FLAG(new->flags, OSPF_LSA_SELF);
|
|
|
|
memcpy(new->data, lsah, length);
|
|
|
|
stream_free(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
static int ospf_router_info_lsa_originate_as(void *arg)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct ospf *top;
|
|
|
|
int rc = -1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Sanity Check */
|
2016-04-19 19:21:17 +02:00
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
|
2018-10-26 19:12:41 +02:00
|
|
|
flog_warn(
|
|
|
|
EC_OSPF_LSA_INSTALL_FAILURE,
|
|
|
|
"RI (%s): wrong flooding scope AREA instead of AS ?",
|
|
|
|
__func__);
|
|
|
|
return rc;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
|
2018-10-26 19:12:41 +02:00
|
|
|
new = ospf_router_info_lsa_new(NULL);
|
|
|
|
top = (struct ospf *)arg;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Check ospf info */
|
2017-08-25 22:51:12 +02:00
|
|
|
if (top == NULL) {
|
2018-10-26 19:12:41 +02:00
|
|
|
zlog_debug("RI (%s): ospf instance not found for vrf id %u",
|
2023-04-07 22:48:24 +02:00
|
|
|
__func__, VRF_DEFAULT);
|
2017-10-09 22:09:48 +02:00
|
|
|
ospf_lsa_unlock(&new);
|
2017-08-25 22:51:12 +02:00
|
|
|
return rc;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Install this LSA into LSDB. */
|
|
|
|
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
|
2018-08-21 03:18:05 +02:00
|
|
|
flog_warn(
|
2018-09-13 20:56:04 +02:00
|
|
|
EC_OSPF_LSA_INSTALL_FAILURE,
|
2018-10-26 19:12:41 +02:00
|
|
|
"RI (%s): ospf_lsa_install() ?", __func__);
|
|
|
|
ospf_lsa_unlock(&new);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update new LSA origination count. */
|
|
|
|
top->lsa_originate_count++;
|
|
|
|
|
|
|
|
/* Flood new LSA through AREA or AS. */
|
|
|
|
SET_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED);
|
|
|
|
ospf_flood_through_as(top, NULL /*nbr */, new);
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Originate Opaque-LSA/ROUTER INFORMATION",
|
|
|
|
new->data->type, &new->data->id);
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ospf_router_info_lsa_originate_area(void *arg)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct ospf *top;
|
|
|
|
struct ospf_ri_area_info *ai = NULL;
|
|
|
|
int rc = -1;
|
|
|
|
|
|
|
|
/* Sanity Check */
|
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
|
|
|
|
flog_warn(
|
|
|
|
EC_OSPF_LSA_INSTALL_FAILURE,
|
|
|
|
"RI (%s): wrong flooding scope AS instead of AREA ?",
|
|
|
|
__func__);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
|
|
|
|
ai = lookup_by_area((struct ospf_area *)arg);
|
|
|
|
if (ai == NULL) {
|
|
|
|
zlog_debug(
|
|
|
|
"RI (%s): There is no context for this Router Information. Stop processing",
|
|
|
|
__func__);
|
|
|
|
return rc;
|
|
|
|
}
|
2023-04-07 22:48:24 +02:00
|
|
|
|
|
|
|
if (ai->area->ospf)
|
2018-10-26 19:12:41 +02:00
|
|
|
top = ai->area->ospf;
|
2023-04-07 22:48:24 +02:00
|
|
|
else
|
|
|
|
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
new = ospf_router_info_lsa_new(ai->area);
|
|
|
|
|
|
|
|
/* Check ospf info */
|
|
|
|
if (top == NULL) {
|
|
|
|
zlog_debug("RI (%s): ospf instance not found for vrf id %u",
|
2023-04-07 22:48:24 +02:00
|
|
|
__func__, VRF_DEFAULT);
|
2016-04-19 19:21:17 +02:00
|
|
|
ospf_lsa_unlock(&new);
|
2017-07-20 19:57:43 +02:00
|
|
|
return rc;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Install this LSA into LSDB. */
|
|
|
|
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
|
|
|
|
flog_warn(
|
|
|
|
EC_OSPF_LSA_INSTALL_FAILURE,
|
|
|
|
"RI (%s): ospf_lsa_install() ?", __func__);
|
|
|
|
ospf_lsa_unlock(&new);
|
|
|
|
return rc;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Update new LSA origination count. */
|
|
|
|
top->lsa_originate_count++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Flood new LSA through AREA or AS. */
|
|
|
|
SET_FLAG(ai->flags, RIFLG_LSA_ENGAGED);
|
|
|
|
ospf_flood_through_area(ai->area, NULL /*nbr */, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Originate Opaque-LSA/ROUTER INFORMATION",
|
|
|
|
new->data->type, &new->data->id);
|
2016-04-19 19:21:17 +02:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
rc = 0;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ospf_router_info_lsa_originate(void *arg)
|
|
|
|
{
|
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
struct ospf_ri_area_info *ai;
|
2016-04-19 19:21:17 +02:00
|
|
|
int rc = -1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-27 16:09:00 +02:00
|
|
|
if (!OspfRI.enabled) {
|
2018-10-26 19:12:41 +02:00
|
|
|
zlog_info("RI (%s): ROUTER INFORMATION is disabled now.",
|
|
|
|
__func__);
|
2016-04-19 19:21:17 +02:00
|
|
|
rc = 0; /* This is not an error case. */
|
2017-07-20 19:57:43 +02:00
|
|
|
return rc;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Check if Router Information LSA is already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
|
|
|
|
if ((CHECK_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED))
|
|
|
|
&& (CHECK_FLAG(OspfRI.as_flags,
|
|
|
|
RIFLG_LSA_FORCED_REFRESH))) {
|
|
|
|
UNSET_FLAG(OspfRI.as_flags, RIFLG_LSA_FORCED_REFRESH);
|
|
|
|
ospf_router_info_lsa_schedule(NULL, REFRESH_THIS_LSA);
|
|
|
|
rc = 0;
|
|
|
|
return rc;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
} else {
|
2018-10-26 19:12:41 +02:00
|
|
|
ai = lookup_by_area((struct ospf_area *)arg);
|
|
|
|
if (ai == NULL) {
|
2018-08-21 15:35:08 +02:00
|
|
|
flog_warn(
|
2018-09-13 20:56:04 +02:00
|
|
|
EC_OSPF_LSA,
|
2018-10-26 19:12:41 +02:00
|
|
|
"RI (%s): Missing area information", __func__);
|
2017-07-20 19:57:43 +02:00
|
|
|
return rc;
|
2018-10-26 19:12:41 +02:00
|
|
|
}
|
|
|
|
if ((CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED))
|
|
|
|
&& (CHECK_FLAG(ai->flags, RIFLG_LSA_FORCED_REFRESH))) {
|
|
|
|
UNSET_FLAG(ai->flags, RIFLG_LSA_FORCED_REFRESH);
|
|
|
|
ospf_router_info_lsa_schedule(ai, REFRESH_THIS_LSA);
|
|
|
|
rc = 0;
|
|
|
|
return rc;
|
|
|
|
}
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Router Information is not yet Engaged, check parameters */
|
2020-08-26 17:27:16 +02:00
|
|
|
if (!is_mandated_params_set(&OspfRI))
|
2018-10-26 19:12:41 +02:00
|
|
|
flog_warn(
|
|
|
|
EC_OSPF_LSA,
|
|
|
|
"RI (%s): lacks mandated ROUTER INFORMATION parameters",
|
|
|
|
__func__);
|
|
|
|
|
|
|
|
/* Ok, let's try to originate an LSA */
|
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
|
|
|
|
rc = ospf_router_info_lsa_originate_as(arg);
|
|
|
|
else
|
|
|
|
rc = ospf_router_info_lsa_originate_area(arg);
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
|
|
|
|
{
|
2018-10-26 19:12:41 +02:00
|
|
|
struct ospf_ri_area_info *ai = NULL;
|
2016-04-19 19:21:17 +02:00
|
|
|
struct ospf_lsa *new = NULL;
|
|
|
|
struct ospf *top;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-27 16:09:00 +02:00
|
|
|
if (!OspfRI.enabled) {
|
2016-04-19 19:21:17 +02:00
|
|
|
/*
|
|
|
|
* This LSA must have flushed before due to ROUTER INFORMATION
|
|
|
|
* status change.
|
|
|
|
* It seems a slip among routers in the routing domain.
|
|
|
|
*/
|
2018-10-26 19:12:41 +02:00
|
|
|
zlog_info("RI (%s): ROUTER INFORMATION is disabled now.",
|
|
|
|
__func__);
|
2016-04-19 19:21:17 +02:00
|
|
|
lsa->data->ls_age =
|
|
|
|
htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Verify that the Router Information ID is supported */
|
|
|
|
if (GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr)) != 0) {
|
2018-08-21 15:35:08 +02:00
|
|
|
flog_warn(
|
2018-09-13 20:56:04 +02:00
|
|
|
EC_OSPF_LSA,
|
2018-10-26 19:12:41 +02:00
|
|
|
"RI (%s): Unsupported Router Information ID",
|
|
|
|
__func__);
|
2017-07-20 19:57:43 +02:00
|
|
|
return NULL;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Process LSA depending of the flooding scope */
|
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
|
|
|
|
/* Get context AREA context */
|
|
|
|
ai = lookup_by_area(lsa->area);
|
|
|
|
if (ai == NULL) {
|
|
|
|
flog_warn(
|
|
|
|
EC_OSPF_LSA,
|
|
|
|
"RI (%s): No associated Area", __func__);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* Flush LSA, if the lsa's age reached to MaxAge. */
|
|
|
|
if (IS_LSA_MAXAGE(lsa)) {
|
|
|
|
UNSET_FLAG(ai->flags, RIFLG_LSA_ENGAGED);
|
|
|
|
ospf_opaque_lsa_flush_schedule(lsa);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
|
|
|
|
new = ospf_router_info_lsa_new(ai->area);
|
|
|
|
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
|
|
|
/* Install this LSA into LSDB. */
|
|
|
|
/* Given "lsa" will be freed in the next function. */
|
2023-04-07 22:48:24 +02:00
|
|
|
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
2018-10-26 19:12:41 +02:00
|
|
|
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
|
|
|
|
flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
|
|
|
|
"RI (%s): ospf_lsa_install() ?", __func__);
|
|
|
|
ospf_lsa_unlock(&new);
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
/* Flood updated LSA through AREA */
|
|
|
|
ospf_flood_through_area(ai->area, NULL /*nbr */, new);
|
|
|
|
|
|
|
|
} else { /* AS Flooding scope */
|
|
|
|
/* Flush LSA, if the lsa's age reached to MaxAge. */
|
|
|
|
if (IS_LSA_MAXAGE(lsa)) {
|
|
|
|
UNSET_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED);
|
|
|
|
ospf_opaque_lsa_flush_schedule(lsa);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/* Create new Opaque-LSA/ROUTER INFORMATION instance. */
|
|
|
|
new = ospf_router_info_lsa_new(NULL);
|
|
|
|
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
|
|
|
/* Install this LSA into LSDB. */
|
|
|
|
/* Given "lsa" will be freed in the next function. */
|
2023-04-07 22:48:24 +02:00
|
|
|
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
2018-10-26 19:12:41 +02:00
|
|
|
if (ospf_lsa_install(top, NULL /*oi */, new) == NULL) {
|
|
|
|
flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
|
|
|
|
"RI (%s): ospf_lsa_install() ?", __func__);
|
|
|
|
ospf_lsa_unlock(&new);
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
/* Flood updated LSA through AS */
|
2016-04-19 19:21:17 +02:00
|
|
|
ospf_flood_through_as(top, NULL /*nbr */, new);
|
2018-10-26 19:12:41 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Debug logging. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Refresh Opaque-LSA/ROUTER INFORMATION",
|
|
|
|
new->data->type, &new->data->id);
|
2016-04-19 19:21:17 +02:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
static void ospf_router_info_lsa_schedule(struct ospf_ri_area_info *ai,
|
|
|
|
enum lsa_opcode opcode)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
struct ospf_lsa lsa;
|
|
|
|
struct lsa_header lsah;
|
|
|
|
struct ospf *top;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t tmp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
memset(&lsa, 0, sizeof(lsa));
|
|
|
|
memset(&lsah, 0, sizeof(lsah));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
zlog_debug("RI (%s): LSA schedule %s%s%s", __func__,
|
2016-04-19 19:21:17 +02:00
|
|
|
opcode == REORIGINATE_THIS_LSA ? "Re-Originate" : "",
|
|
|
|
opcode == REFRESH_THIS_LSA ? "Refresh" : "",
|
|
|
|
opcode == FLUSH_THIS_LSA ? "Flush" : "");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Check LSA flags state coherence and collect area information */
|
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA) {
|
|
|
|
if ((ai == NULL) || (ai->area == NULL)) {
|
|
|
|
flog_warn(
|
|
|
|
EC_OSPF_LSA,
|
|
|
|
"RI (%s): Router Info is Area scope flooding but area is not set",
|
|
|
|
__func__);
|
|
|
|
return;
|
|
|
|
}
|
2017-07-20 19:57:43 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
if (!CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED)
|
|
|
|
&& (opcode != REORIGINATE_THIS_LSA))
|
|
|
|
return;
|
2017-07-20 19:57:43 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
if (CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED)
|
|
|
|
&& (opcode == REORIGINATE_THIS_LSA))
|
|
|
|
opcode = REFRESH_THIS_LSA;
|
|
|
|
|
|
|
|
lsa.area = ai->area;
|
|
|
|
top = ai->area->ospf;
|
|
|
|
} else {
|
|
|
|
if (!CHECK_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED)
|
|
|
|
&& (opcode != REORIGINATE_THIS_LSA))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (CHECK_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED)
|
|
|
|
&& (opcode == REORIGINATE_THIS_LSA))
|
|
|
|
opcode = REFRESH_THIS_LSA;
|
|
|
|
|
|
|
|
top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
|
|
|
|
lsa.area = NULL;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2018-10-26 19:12:41 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
lsa.data = &lsah;
|
|
|
|
lsah.type = OspfRI.scope;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* LSA ID is set to 0 for the Router Information. See RFC 4970 */
|
|
|
|
tmp = SET_OPAQUE_LSID(OPAQUE_TYPE_ROUTER_INFORMATION_LSA, 0);
|
|
|
|
lsah.id.s_addr = htonl(tmp);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
switch (opcode) {
|
|
|
|
case REORIGINATE_THIS_LSA:
|
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA)
|
|
|
|
ospf_opaque_lsa_reoriginate_schedule(
|
2018-10-26 19:12:41 +02:00
|
|
|
(void *)ai->area, OSPF_OPAQUE_AREA_LSA,
|
2016-04-19 19:21:17 +02:00
|
|
|
OPAQUE_TYPE_ROUTER_INFORMATION_LSA);
|
|
|
|
else
|
|
|
|
ospf_opaque_lsa_reoriginate_schedule(
|
|
|
|
(void *)top, OSPF_OPAQUE_AS_LSA,
|
|
|
|
OPAQUE_TYPE_ROUTER_INFORMATION_LSA);
|
|
|
|
break;
|
|
|
|
case REFRESH_THIS_LSA:
|
|
|
|
ospf_opaque_lsa_refresh_schedule(&lsa);
|
|
|
|
break;
|
|
|
|
case FLUSH_THIS_LSA:
|
2018-10-26 19:12:41 +02:00
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AREA_LSA)
|
|
|
|
UNSET_FLAG(ai->flags, RIFLG_LSA_ENGAGED);
|
|
|
|
else
|
|
|
|
UNSET_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED);
|
2016-04-19 19:21:17 +02:00
|
|
|
ospf_opaque_lsa_flush_schedule(&lsa);
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Callback to handle Segment Routing information */
|
|
|
|
static int ospf_router_info_lsa_update(struct ospf_lsa *lsa)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Sanity Check */
|
|
|
|
if (lsa == NULL) {
|
2018-10-26 19:12:41 +02:00
|
|
|
flog_warn(EC_OSPF_LSA, "RI (%s): Abort! LSA is NULL",
|
2018-08-21 15:35:08 +02:00
|
|
|
__func__);
|
2018-01-18 19:11:11 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-02-05 20:24:17 +01:00
|
|
|
/* Process only Opaque LSA */
|
|
|
|
if ((lsa->data->type != OSPF_OPAQUE_AREA_LSA)
|
|
|
|
&& (lsa->data->type != OSPF_OPAQUE_AS_LSA))
|
2018-01-18 19:11:11 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Process only Router Information LSA */
|
2018-01-29 17:58:53 +01:00
|
|
|
if (GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr))
|
|
|
|
!= OPAQUE_TYPE_ROUTER_INFORMATION_LSA)
|
2018-01-18 19:11:11 +01:00
|
|
|
return 0;
|
|
|
|
|
2018-02-05 20:24:17 +01:00
|
|
|
/* Check if it is not my LSA */
|
|
|
|
if (IS_LSA_SELF(lsa))
|
|
|
|
return 0;
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Check if Router Info & Segment Routing are enable */
|
|
|
|
if (!OspfRI.enabled || !OspfRI.sr_info.enabled)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Call Segment Routing LSA update or deletion */
|
|
|
|
if (!IS_LSA_MAXAGE(lsa))
|
|
|
|
ospf_sr_ri_lsa_update(lsa);
|
|
|
|
else
|
|
|
|
ospf_sr_ri_lsa_delete(lsa);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/*------------------------------------------------------------------------*
|
2022-04-01 22:27:55 +02:00
|
|
|
* Following are vty session control functions.
|
2016-04-19 19:21:17 +02:00
|
|
|
*------------------------------------------------------------------------*/
|
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
#define check_tlv_size(size, msg) \
|
|
|
|
do { \
|
|
|
|
if (ntohs(tlvh->length) > size) { \
|
|
|
|
if (vty != NULL) \
|
|
|
|
vty_out(vty, " Wrong %s TLV size: %d(%d)\n", \
|
|
|
|
msg, ntohs(tlvh->length), size); \
|
|
|
|
else \
|
2021-05-19 20:51:23 +02:00
|
|
|
zlog_debug(" Wrong %s TLV size: %d(%d)", \
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
msg, ntohs(tlvh->length), size); \
|
|
|
|
return size + TLV_HDR_SIZE; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint16_t show_vty_router_cap(struct vty *vty, struct tlv_header *tlvh)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
struct ri_tlv_router_cap *top = (struct ri_tlv_router_cap *)tlvh;
|
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
check_tlv_size(RI_TLV_CAPABILITIES_SIZE, "Router Capabilities");
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (vty != NULL)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " Router Capabilities: 0x%x\n",
|
|
|
|
ntohl(top->value));
|
2017-06-21 05:10:57 +02:00
|
|
|
else
|
|
|
|
zlog_debug(" Router Capabilities: 0x%x", ntohl(top->value));
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
return TLV_SIZE(tlvh);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
|
|
|
|
struct tlv_header *tlvh)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
struct ri_pce_subtlv_address *top =
|
|
|
|
(struct ri_pce_subtlv_address *)tlvh;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
if (ntohs(top->address.type) == PCE_ADDRESS_IPV4) {
|
|
|
|
check_tlv_size(PCE_ADDRESS_IPV4_SIZE, "PCE Address");
|
2016-04-19 19:21:17 +02:00
|
|
|
if (vty != NULL)
|
2020-10-21 19:56:26 +02:00
|
|
|
vty_out(vty, " PCE Address: %pI4\n",
|
|
|
|
&top->address.value);
|
2017-06-21 05:10:57 +02:00
|
|
|
else
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug(" PCE Address: %pI4",
|
|
|
|
&top->address.value);
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
} else if (ntohs(top->address.type) == PCE_ADDRESS_IPV6) {
|
2016-04-19 19:21:17 +02:00
|
|
|
/* TODO: Add support to IPv6 with inet_ntop() */
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
check_tlv_size(PCE_ADDRESS_IPV6_SIZE, "PCE Address");
|
2016-04-19 19:21:17 +02:00
|
|
|
if (vty != NULL)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " PCE Address: 0x%x\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
ntohl(top->address.value.s_addr));
|
|
|
|
else
|
|
|
|
zlog_debug(" PCE Address: 0x%x",
|
|
|
|
ntohl(top->address.value.s_addr));
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
} else {
|
|
|
|
if (vty != NULL)
|
|
|
|
vty_out(vty, " Wrong PCE Address type: 0x%x\n",
|
|
|
|
ntohl(top->address.type));
|
|
|
|
else
|
|
|
|
zlog_debug(" Wrong PCE Address type: 0x%x",
|
|
|
|
ntohl(top->address.type));
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
return TLV_SIZE(tlvh);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint16_t show_vty_pce_subtlv_path_scope(struct vty *vty,
|
|
|
|
struct tlv_header *tlvh)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
struct ri_pce_subtlv_path_scope *top =
|
|
|
|
(struct ri_pce_subtlv_path_scope *)tlvh;
|
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
check_tlv_size(RI_PCE_SUBTLV_PATH_SCOPE_SIZE, "PCE Path Scope");
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (vty != NULL)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " PCE Path Scope: 0x%x\n", ntohl(top->value));
|
2017-06-21 05:10:57 +02:00
|
|
|
else
|
|
|
|
zlog_debug(" PCE Path Scope: 0x%x", ntohl(top->value));
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
return TLV_SIZE(tlvh);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
|
|
|
|
struct tlv_header *tlvh)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
struct ri_pce_subtlv_domain *top = (struct ri_pce_subtlv_domain *)tlvh;
|
|
|
|
struct in_addr tmp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
check_tlv_size(RI_PCE_SUBTLV_DOMAIN_SIZE, "PCE Domain");
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
|
|
|
|
tmp.s_addr = top->value;
|
|
|
|
if (vty != NULL)
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
vty_out(vty, " PCE Domain Area: %pI4\n", &tmp);
|
2017-06-21 05:10:57 +02:00
|
|
|
else
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
zlog_debug(" PCE Domain Area: %pI4", &tmp);
|
|
|
|
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
|
2016-04-19 19:21:17 +02:00
|
|
|
if (vty != NULL)
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
vty_out(vty, " PCE Domain AS: %d\n",
|
2017-07-13 17:49:13 +02:00
|
|
|
ntohl(top->value));
|
2017-06-21 05:10:57 +02:00
|
|
|
else
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
zlog_debug(" PCE Domain AS: %d", ntohl(top->value));
|
|
|
|
} else {
|
|
|
|
if (vty != NULL)
|
|
|
|
vty_out(vty, " Wrong PCE Domain type: %d\n",
|
|
|
|
ntohl(top->type));
|
|
|
|
else
|
|
|
|
zlog_debug(" Wrong PCE Domain type: %d",
|
|
|
|
ntohl(top->type));
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
return TLV_SIZE(tlvh);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
|
|
|
|
struct tlv_header *tlvh)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
struct ri_pce_subtlv_neighbor *top =
|
|
|
|
(struct ri_pce_subtlv_neighbor *)tlvh;
|
|
|
|
struct in_addr tmp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
check_tlv_size(RI_PCE_SUBTLV_NEIGHBOR_SIZE, "PCE Neighbor");
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
|
|
|
|
tmp.s_addr = top->value;
|
|
|
|
if (vty != NULL)
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
vty_out(vty, " PCE Neighbor Area: %pI4\n", &tmp);
|
2017-06-21 05:10:57 +02:00
|
|
|
else
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
zlog_debug(" PCE Neighbor Area: %pI4", &tmp);
|
|
|
|
} else if (ntohs(top->type) == PCE_DOMAIN_TYPE_AS) {
|
2016-04-19 19:21:17 +02:00
|
|
|
if (vty != NULL)
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
vty_out(vty, " PCE Neighbor AS: %d\n",
|
2017-07-13 17:49:13 +02:00
|
|
|
ntohl(top->value));
|
2017-06-21 05:10:57 +02:00
|
|
|
else
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
zlog_debug(" PCE Neighbor AS: %d",
|
2017-06-21 05:10:57 +02:00
|
|
|
ntohl(top->value));
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
} else {
|
|
|
|
if (vty != NULL)
|
|
|
|
vty_out(vty, " Wrong PCE Neighbor type: %d\n",
|
|
|
|
ntohl(top->type));
|
|
|
|
else
|
|
|
|
zlog_debug(" Wrong PCE Neighbor type: %d",
|
|
|
|
ntohl(top->type));
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
return TLV_SIZE(tlvh);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint16_t show_vty_pce_subtlv_cap_flag(struct vty *vty,
|
|
|
|
struct tlv_header *tlvh)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
struct ri_pce_subtlv_cap_flag *top =
|
|
|
|
(struct ri_pce_subtlv_cap_flag *)tlvh;
|
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
check_tlv_size(RI_PCE_SUBTLV_CAP_FLAG_SIZE, "PCE Capabilities");
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (vty != NULL)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " PCE Capabilities Flag: 0x%x\n",
|
|
|
|
ntohl(top->value));
|
2017-06-21 05:10:57 +02:00
|
|
|
else
|
|
|
|
zlog_debug(" PCE Capabilities Flag: 0x%x",
|
|
|
|
ntohl(top->value));
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
return TLV_SIZE(tlvh);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
static uint16_t show_vty_unknown_tlv(struct vty *vty, struct tlv_header *tlvh,
|
|
|
|
size_t buf_size)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
if (TLV_SIZE(tlvh) > buf_size) {
|
|
|
|
if (vty != NULL)
|
|
|
|
vty_out(vty,
|
|
|
|
" TLV size %d exceeds buffer size. Abort!",
|
|
|
|
TLV_SIZE(tlvh));
|
|
|
|
else
|
|
|
|
zlog_debug(
|
|
|
|
" TLV size %d exceeds buffer size. Abort!",
|
|
|
|
TLV_SIZE(tlvh));
|
|
|
|
return buf_size;
|
|
|
|
}
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (vty != NULL)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " Unknown TLV: [type(0x%x), length(0x%x)]\n",
|
2017-06-21 05:10:57 +02:00
|
|
|
ntohs(tlvh->type), ntohs(tlvh->length));
|
|
|
|
else
|
|
|
|
zlog_debug(" Unknown TLV: [type(0x%x), length(0x%x)]",
|
|
|
|
ntohs(tlvh->type), ntohs(tlvh->length));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-20 19:57:43 +02:00
|
|
|
return TLV_SIZE(tlvh);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint16_t show_vty_pce_info(struct vty *vty, struct tlv_header *ri,
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
size_t buf_size)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
2017-07-20 19:57:43 +02:00
|
|
|
struct tlv_header *tlvh;
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
uint16_t length = ntohs(ri->length);
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t sum = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
/* Verify that TLV length is valid against remaining buffer size */
|
|
|
|
if (length > buf_size) {
|
|
|
|
vty_out(vty,
|
|
|
|
" PCE Info TLV size %d exceeds buffer size. Abort!\n",
|
|
|
|
length);
|
|
|
|
return buf_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (tlvh = ri; sum < length; tlvh = TLV_HDR_NEXT(tlvh)) {
|
2016-04-19 19:21:17 +02:00
|
|
|
switch (ntohs(tlvh->type)) {
|
|
|
|
case RI_PCE_SUBTLV_ADDRESS:
|
|
|
|
sum += show_vty_pce_subtlv_address(vty, tlvh);
|
|
|
|
break;
|
|
|
|
case RI_PCE_SUBTLV_PATH_SCOPE:
|
|
|
|
sum += show_vty_pce_subtlv_path_scope(vty, tlvh);
|
|
|
|
break;
|
|
|
|
case RI_PCE_SUBTLV_DOMAIN:
|
|
|
|
sum += show_vty_pce_subtlv_domain(vty, tlvh);
|
|
|
|
break;
|
|
|
|
case RI_PCE_SUBTLV_NEIGHBOR:
|
|
|
|
sum += show_vty_pce_subtlv_neighbor(vty, tlvh);
|
|
|
|
break;
|
|
|
|
case RI_PCE_SUBTLV_CAP_FLAG:
|
|
|
|
sum += show_vty_pce_subtlv_cap_flag(vty, tlvh);
|
|
|
|
break;
|
|
|
|
default:
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
sum += show_vty_unknown_tlv(vty, tlvh, length - sum);
|
2016-04-19 19:21:17 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sum;
|
|
|
|
}
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
/* Display Segment Routing Algorithm TLV information */
|
2018-01-23 12:19:50 +01:00
|
|
|
static uint16_t show_vty_sr_algorithm(struct vty *vty, struct tlv_header *tlvh)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
|
|
|
struct ri_sr_tlv_sr_algorithm *algo =
|
|
|
|
(struct ri_sr_tlv_sr_algorithm *)tlvh;
|
|
|
|
int i;
|
2018-01-29 17:58:53 +01:00
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
check_tlv_size(ALGORITHM_COUNT, "Segment Routing Algorithm");
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
if (vty != NULL) {
|
|
|
|
vty_out(vty, " Segment Routing Algorithm TLV:\n");
|
|
|
|
for (i = 0; i < ntohs(algo->header.length); i++) {
|
|
|
|
switch (algo->value[i]) {
|
|
|
|
case 0:
|
|
|
|
vty_out(vty, " Algorithm %d: SPF\n", i);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
vty_out(vty, " Algorithm %d: Strict SPF\n",
|
|
|
|
i);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out(vty,
|
|
|
|
" Algorithm %d: Unknown value %d\n", i,
|
|
|
|
algo->value[i]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
} else {
|
2019-03-14 19:41:15 +01:00
|
|
|
zlog_debug(" Segment Routing Algorithm TLV:");
|
2018-01-18 19:11:11 +01:00
|
|
|
for (i = 0; i < ntohs(algo->header.length); i++)
|
|
|
|
switch (algo->value[i]) {
|
|
|
|
case 0:
|
2019-03-14 19:41:15 +01:00
|
|
|
zlog_debug(" Algorithm %d: SPF", i);
|
2018-01-18 19:11:11 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2019-03-14 19:41:15 +01:00
|
|
|
zlog_debug(" Algorithm %d: Strict SPF", i);
|
2018-01-18 19:11:11 +01:00
|
|
|
break;
|
|
|
|
default:
|
2020-03-24 19:15:04 +01:00
|
|
|
zlog_debug(" Algorithm %d: Unknown value %d",
|
|
|
|
i, algo->value[i]);
|
2018-01-18 19:11:11 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TLV_SIZE(tlvh);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Display Segment Routing SID/Label Range TLV information */
|
2018-01-23 12:19:50 +01:00
|
|
|
static uint16_t show_vty_sr_range(struct vty *vty, struct tlv_header *tlvh)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
|
|
|
struct ri_sr_tlv_sid_label_range *range =
|
|
|
|
(struct ri_sr_tlv_sid_label_range *)tlvh;
|
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
check_tlv_size(RI_SR_TLV_LABEL_RANGE_SIZE, "SR Label Range");
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
if (vty != NULL) {
|
|
|
|
vty_out(vty,
|
2020-06-18 19:46:28 +02:00
|
|
|
" Segment Routing %s Range TLV:\n"
|
2018-01-18 19:11:11 +01:00
|
|
|
" Range Size = %d\n"
|
|
|
|
" SID Label = %d\n\n",
|
2020-06-18 19:46:28 +02:00
|
|
|
ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
|
|
|
|
? "Global"
|
|
|
|
: "Local",
|
2018-01-18 19:11:11 +01:00
|
|
|
GET_RANGE_SIZE(ntohl(range->size)),
|
|
|
|
GET_LABEL(ntohl(range->lower.value)));
|
|
|
|
} else {
|
|
|
|
zlog_debug(
|
2021-02-14 15:35:07 +01:00
|
|
|
" Segment Routing %s Range TLV: Range Size = %d SID Label = %d",
|
2020-06-18 19:46:28 +02:00
|
|
|
ntohs(range->header.type) == RI_SR_TLV_SRGB_LABEL_RANGE
|
|
|
|
? "Global"
|
|
|
|
: "Local",
|
2018-01-18 19:11:11 +01:00
|
|
|
GET_RANGE_SIZE(ntohl(range->size)),
|
|
|
|
GET_LABEL(ntohl(range->lower.value)));
|
|
|
|
}
|
|
|
|
|
|
|
|
return TLV_SIZE(tlvh);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Display Segment Routing Maximum Stack Depth TLV information */
|
2018-01-23 12:19:50 +01:00
|
|
|
static uint16_t show_vty_sr_msd(struct vty *vty, struct tlv_header *tlvh)
|
2018-01-18 19:11:11 +01:00
|
|
|
{
|
|
|
|
struct ri_sr_tlv_node_msd *msd = (struct ri_sr_tlv_node_msd *)tlvh;
|
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
check_tlv_size(RI_SR_TLV_NODE_MSD_SIZE, "Node Maximum Stack Depth");
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
if (vty != NULL) {
|
|
|
|
vty_out(vty,
|
|
|
|
" Segment Routing MSD TLV:\n"
|
|
|
|
" Node Maximum Stack Depth = %d\n",
|
|
|
|
msd->value);
|
|
|
|
} else {
|
|
|
|
zlog_debug(
|
2021-02-14 15:35:07 +01:00
|
|
|
" Segment Routing MSD TLV: Node Maximum Stack Depth = %d",
|
2018-01-18 19:11:11 +01:00
|
|
|
msd->value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TLV_SIZE(tlvh);
|
|
|
|
}
|
|
|
|
|
2021-10-08 02:06:01 +02:00
|
|
|
static void ospf_router_info_show_info(struct vty *vty,
|
|
|
|
struct json_object *json,
|
|
|
|
struct ospf_lsa *lsa)
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
2020-04-08 07:57:15 +02:00
|
|
|
struct lsa_header *lsah = lsa->data;
|
2017-07-20 19:57:43 +02:00
|
|
|
struct tlv_header *tlvh;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t length = 0, sum = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-10-08 02:06:01 +02:00
|
|
|
if (json)
|
|
|
|
return;
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Initialize TLV browsing */
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
length = lsa->size - OSPF_LSA_HEADER_SIZE;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh;
|
2017-07-20 19:57:43 +02:00
|
|
|
tlvh = TLV_HDR_NEXT(tlvh)) {
|
2016-04-19 19:21:17 +02:00
|
|
|
switch (ntohs(tlvh->type)) {
|
|
|
|
case RI_TLV_CAPABILITIES:
|
|
|
|
sum += show_vty_router_cap(vty, tlvh);
|
|
|
|
break;
|
|
|
|
case RI_TLV_PCE:
|
|
|
|
tlvh++;
|
2017-07-20 19:57:43 +02:00
|
|
|
sum += TLV_HDR_SIZE;
|
2016-04-19 19:21:17 +02:00
|
|
|
sum += show_vty_pce_info(vty, tlvh, length - sum);
|
|
|
|
break;
|
2018-01-18 19:11:11 +01:00
|
|
|
case RI_SR_TLV_SR_ALGORITHM:
|
|
|
|
sum += show_vty_sr_algorithm(vty, tlvh);
|
|
|
|
break;
|
2020-06-18 19:46:28 +02:00
|
|
|
case RI_SR_TLV_SRGB_LABEL_RANGE:
|
|
|
|
case RI_SR_TLV_SRLB_LABEL_RANGE:
|
2018-01-18 19:11:11 +01:00
|
|
|
sum += show_vty_sr_range(vty, tlvh);
|
|
|
|
break;
|
|
|
|
case RI_SR_TLV_NODE_MSD:
|
|
|
|
sum += show_vty_sr_msd(vty, tlvh);
|
|
|
|
break;
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
default:
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
sum += show_vty_unknown_tlv(vty, tlvh, length);
|
2016-04-19 19:21:17 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ospf_router_info_config_write_router(struct vty *vty)
|
|
|
|
{
|
|
|
|
struct ospf_pce_info *pce = &OspfRI.pce_info;
|
|
|
|
struct listnode *node;
|
|
|
|
struct ri_pce_subtlv_domain *domain;
|
|
|
|
struct ri_pce_subtlv_neighbor *neighbor;
|
|
|
|
struct in_addr tmp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
if (!OspfRI.enabled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA)
|
|
|
|
vty_out(vty, " router-info as\n");
|
|
|
|
else
|
2018-10-26 19:12:41 +02:00
|
|
|
vty_out(vty, " router-info area\n");
|
2018-01-18 19:11:11 +01:00
|
|
|
|
|
|
|
if (OspfRI.pce_info.enabled) {
|
|
|
|
|
|
|
|
if (pce->pce_address.header.type != 0)
|
2020-10-21 19:56:26 +02:00
|
|
|
vty_out(vty, " pce address %pI4\n",
|
|
|
|
&pce->pce_address.address.value);
|
2018-01-18 19:11:11 +01:00
|
|
|
|
|
|
|
if (pce->pce_cap_flag.header.type != 0)
|
|
|
|
vty_out(vty, " pce flag 0x%x\n",
|
|
|
|
ntohl(pce->pce_cap_flag.value));
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
|
|
|
|
if (domain->header.type != 0) {
|
|
|
|
if (domain->type == PCE_DOMAIN_TYPE_AREA) {
|
|
|
|
tmp.s_addr = domain->value;
|
2020-10-21 19:56:26 +02:00
|
|
|
vty_out(vty, " pce domain area %pI4\n",
|
|
|
|
&tmp);
|
2018-01-18 19:11:11 +01:00
|
|
|
} else {
|
|
|
|
vty_out(vty, " pce domain as %d\n",
|
|
|
|
ntohl(domain->value));
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2018-01-18 19:11:11 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
|
|
|
|
if (neighbor->header.type != 0) {
|
|
|
|
if (neighbor->type == PCE_DOMAIN_TYPE_AREA) {
|
|
|
|
tmp.s_addr = neighbor->value;
|
2020-10-21 19:56:26 +02:00
|
|
|
vty_out(vty,
|
|
|
|
" pce neighbor area %pI4\n",
|
|
|
|
&tmp);
|
2018-01-18 19:11:11 +01:00
|
|
|
} else {
|
|
|
|
vty_out(vty, " pce neighbor as %d\n",
|
|
|
|
ntohl(neighbor->value));
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-20 19:57:43 +02:00
|
|
|
}
|
2018-01-18 19:11:11 +01:00
|
|
|
|
|
|
|
if (pce->pce_scope.header.type != 0)
|
|
|
|
vty_out(vty, " pce scope 0x%x\n",
|
|
|
|
ntohl(OspfRI.pce_info.pce_scope.value));
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------------*
|
2022-04-01 22:27:55 +02:00
|
|
|
* Following are vty command functions.
|
2016-04-19 19:21:17 +02:00
|
|
|
*------------------------------------------------------------------------*/
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Simple wrapper schedule RI LSA action in function of the scope */
|
|
|
|
static void ospf_router_info_schedule(enum lsa_opcode opcode)
|
|
|
|
{
|
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct ospf_ri_area_info *ai;
|
|
|
|
|
|
|
|
if (OspfRI.scope == OSPF_OPAQUE_AS_LSA) {
|
|
|
|
if (CHECK_FLAG(OspfRI.as_flags, RIFLG_LSA_ENGAGED))
|
|
|
|
ospf_router_info_lsa_schedule(NULL, opcode);
|
|
|
|
else if (opcode == REORIGINATE_THIS_LSA)
|
|
|
|
ospf_router_info_lsa_schedule(NULL, opcode);
|
|
|
|
} else {
|
|
|
|
for (ALL_LIST_ELEMENTS(OspfRI.area_info, node, nnode, ai)) {
|
|
|
|
if (CHECK_FLAG(ai->flags, RIFLG_LSA_ENGAGED))
|
|
|
|
ospf_router_info_lsa_schedule(ai, opcode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
DEFUN (router_info,
|
|
|
|
router_info_area_cmd,
|
2018-10-26 19:12:41 +02:00
|
|
|
"router-info <as|area [A.B.C.D]>",
|
2016-04-19 19:21:17 +02:00
|
|
|
OSPF_RI_STR
|
2016-09-29 03:26:55 +02:00
|
|
|
"Enable the Router Information functionality with AS flooding scope\n"
|
2016-04-19 19:21:17 +02:00
|
|
|
"Enable the Router Information functionality with Area flooding scope\n"
|
2018-10-26 19:12:41 +02:00
|
|
|
"OSPF area ID in IP format (deprecated)\n")
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
2018-10-26 19:12:41 +02:00
|
|
|
int idx_mode = 1;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t scope;
|
2023-04-07 22:48:24 +02:00
|
|
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-27 16:09:00 +02:00
|
|
|
if (OspfRI.enabled)
|
2016-04-19 19:21:17 +02:00
|
|
|
return CMD_SUCCESS;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-04-07 22:48:24 +02:00
|
|
|
/* Check that the OSPF is using default VRF */
|
|
|
|
if (ospf->vrf_id != VRF_DEFAULT) {
|
|
|
|
vty_out(vty,
|
|
|
|
"Router Information is only supported in default VRF\n");
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
}
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* Check and get Area value if present */
|
2018-10-26 19:12:41 +02:00
|
|
|
if (strncmp(argv[idx_mode]->arg, "as", 2) == 0)
|
2016-04-19 19:21:17 +02:00
|
|
|
scope = OSPF_OPAQUE_AS_LSA;
|
2018-10-26 19:12:41 +02:00
|
|
|
else
|
|
|
|
scope = OSPF_OPAQUE_AREA_LSA;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/* First start to register Router Information callbacks */
|
2018-10-26 19:12:41 +02:00
|
|
|
if (!OspfRI.registered && (ospf_router_info_register(scope)) != 0) {
|
2018-08-21 15:35:08 +02:00
|
|
|
vty_out(vty,
|
|
|
|
"%% Unable to register Router Information callbacks.");
|
|
|
|
flog_err(
|
2018-09-13 20:56:04 +02:00
|
|
|
EC_OSPF_INIT_FAIL,
|
2018-10-26 19:12:41 +02:00
|
|
|
"RI (%s): Unable to register Router Information callbacks. Abort!",
|
|
|
|
__func__);
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-27 16:09:00 +02:00
|
|
|
OspfRI.enabled = true;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug("RI-> Router Information (%s flooding): OFF -> ON",
|
|
|
|
OspfRI.scope == OSPF_OPAQUE_AREA_LSA ? "Area"
|
|
|
|
: "AS");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
/*
|
|
|
|
* Following code is intended to handle two cases;
|
|
|
|
*
|
|
|
|
* 1) Router Information was disabled at startup time, but now become
|
|
|
|
* enabled.
|
|
|
|
* 2) Router Information was once enabled then disabled, and now enabled
|
|
|
|
* again.
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
initialize_params(&OspfRI);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
/* Originate or Refresh RI LSA if already engaged */
|
|
|
|
ospf_router_info_schedule(REORIGINATE_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFUN (no_router_info,
|
|
|
|
no_router_info_cmd,
|
|
|
|
"no router-info",
|
|
|
|
NO_STR
|
|
|
|
"Disable the Router Information functionality\n")
|
|
|
|
{
|
|
|
|
|
2017-07-27 16:09:00 +02:00
|
|
|
if (!OspfRI.enabled)
|
2016-04-19 19:21:17 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug("RI-> Router Information: ON -> OFF");
|
|
|
|
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(FLUSH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2017-07-27 16:09:00 +02:00
|
|
|
OspfRI.enabled = false;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-10-25 21:18:50 +02:00
|
|
|
static int ospf_ri_enabled(struct vty *vty)
|
|
|
|
{
|
2017-07-27 16:09:00 +02:00
|
|
|
if (OspfRI.enabled)
|
2016-10-25 21:18:50 +02:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (vty)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "%% OSPF RI is not turned on\n");
|
2016-10-25 21:18:50 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
DEFUN (pce_address,
|
|
|
|
pce_address_cmd,
|
|
|
|
"pce address A.B.C.D",
|
|
|
|
PCE_STR
|
|
|
|
"Stable IP address of the PCE\n"
|
|
|
|
"PCE address in IPv4 address format\n")
|
|
|
|
{
|
2016-09-23 22:01:26 +02:00
|
|
|
int idx_ipv4 = 2;
|
2016-04-19 19:21:17 +02:00
|
|
|
struct in_addr value;
|
|
|
|
struct ospf_pce_info *pi = &OspfRI.pce_info;
|
|
|
|
|
2016-10-25 21:18:50 +02:00
|
|
|
if (!ospf_ri_enabled(vty))
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-10-25 21:18:50 +02:00
|
|
|
|
2016-09-23 22:01:26 +02:00
|
|
|
if (!inet_aton(argv[idx_ipv4]->arg, &value)) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "Please specify PCE Address by A.B.C.D\n");
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ntohs(pi->pce_address.header.type) == 0
|
|
|
|
|| ntohl(pi->pce_address.address.value.s_addr)
|
|
|
|
!= ntohl(value.s_addr)) {
|
|
|
|
|
|
|
|
set_pce_address(value, pi);
|
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_pce_address,
|
|
|
|
no_pce_address_cmd,
|
2016-11-04 21:16:07 +01:00
|
|
|
"no pce address [A.B.C.D]",
|
2016-04-19 19:21:17 +02:00
|
|
|
NO_STR
|
|
|
|
PCE_STR
|
2016-10-26 14:11:12 +02:00
|
|
|
"Disable PCE address\n"
|
|
|
|
"PCE address in IPv4 address format\n")
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
|
2018-06-14 19:19:44 +02:00
|
|
|
unset_param(&OspfRI.pce_info.pce_address);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (pce_path_scope,
|
|
|
|
pce_path_scope_cmd,
|
|
|
|
"pce scope BITPATTERN",
|
|
|
|
PCE_STR
|
|
|
|
"Path scope visibilities of the PCE for path computation\n"
|
|
|
|
"32-bit Hexadecimal value\n")
|
|
|
|
{
|
2016-09-23 22:01:26 +02:00
|
|
|
int idx_bitpattern = 2;
|
2016-04-19 19:21:17 +02:00
|
|
|
uint32_t scope;
|
|
|
|
struct ospf_pce_info *pi = &OspfRI.pce_info;
|
|
|
|
|
2016-10-25 21:18:50 +02:00
|
|
|
if (!ospf_ri_enabled(vty))
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-10-25 21:18:50 +02:00
|
|
|
|
2016-09-23 22:01:26 +02:00
|
|
|
if (sscanf(argv[idx_bitpattern]->arg, "0x%x", &scope) != 1) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "pce_path_scope: fscanf: %s\n",
|
|
|
|
safe_strerror(errno));
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ntohl(pi->pce_scope.header.type) == 0
|
|
|
|
|| scope != pi->pce_scope.value) {
|
|
|
|
set_pce_path_scope(scope, pi);
|
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_pce_path_scope,
|
|
|
|
no_pce_path_scope_cmd,
|
2016-11-04 21:16:07 +01:00
|
|
|
"no pce scope [BITPATTERN]",
|
2016-04-19 19:21:17 +02:00
|
|
|
NO_STR
|
|
|
|
PCE_STR
|
2016-10-26 14:11:12 +02:00
|
|
|
"Disable PCE path scope\n"
|
|
|
|
"32-bit Hexadecimal value\n")
|
2016-04-19 19:21:17 +02:00
|
|
|
{
|
|
|
|
|
2018-06-14 19:19:44 +02:00
|
|
|
unset_param(&OspfRI.pce_info.pce_address);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (pce_domain,
|
|
|
|
pce_domain_cmd,
|
2016-09-23 15:47:20 +02:00
|
|
|
"pce domain as (0-65535)",
|
2016-04-19 19:21:17 +02:00
|
|
|
PCE_STR
|
|
|
|
"Configure PCE domain AS number\n"
|
|
|
|
"AS number where the PCE as visibilities for path computation\n"
|
|
|
|
"AS number in decimal <0-65535>\n")
|
|
|
|
{
|
2016-09-23 22:01:26 +02:00
|
|
|
int idx_number = 3;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
uint32_t as;
|
|
|
|
struct ospf_pce_info *pce = &OspfRI.pce_info;
|
|
|
|
struct listnode *node;
|
|
|
|
struct ri_pce_subtlv_domain *domain;
|
|
|
|
|
2016-10-25 21:18:50 +02:00
|
|
|
if (!ospf_ri_enabled(vty))
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-10-25 21:18:50 +02:00
|
|
|
|
2018-07-02 17:32:05 +02:00
|
|
|
if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "pce_domain: fscanf: %s\n", safe_strerror(errno));
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the domain is not already in the domain list */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
|
|
|
|
if (ntohl(domain->header.type) == 0 && as == domain->value)
|
2016-10-25 21:18:50 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create new domain if not found */
|
|
|
|
set_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
|
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2016-10-25 21:18:50 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_pce_domain,
|
|
|
|
no_pce_domain_cmd,
|
2016-09-23 15:47:20 +02:00
|
|
|
"no pce domain as (0-65535)",
|
2016-04-19 19:21:17 +02:00
|
|
|
NO_STR
|
|
|
|
PCE_STR
|
|
|
|
"Disable PCE domain AS number\n"
|
|
|
|
"AS number where the PCE as visibilities for path computation\n"
|
|
|
|
"AS number in decimal <0-65535>\n")
|
|
|
|
{
|
2016-09-23 22:01:26 +02:00
|
|
|
int idx_number = 4;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
uint32_t as;
|
|
|
|
struct ospf_pce_info *pce = &OspfRI.pce_info;
|
|
|
|
|
2018-07-02 17:32:05 +02:00
|
|
|
if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "no_pce_domain: fscanf: %s\n",
|
|
|
|
safe_strerror(errno));
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Unset corresponding PCE domain */
|
|
|
|
unset_pce_domain(PCE_DOMAIN_TYPE_AS, as, pce);
|
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (pce_neigbhor,
|
|
|
|
pce_neighbor_cmd,
|
2016-09-23 15:47:20 +02:00
|
|
|
"pce neighbor as (0-65535)",
|
2016-04-19 19:21:17 +02:00
|
|
|
PCE_STR
|
|
|
|
"Configure PCE neighbor domain AS number\n"
|
|
|
|
"AS number of PCE neighbors\n"
|
|
|
|
"AS number in decimal <0-65535>\n")
|
|
|
|
{
|
2016-09-23 22:01:26 +02:00
|
|
|
int idx_number = 3;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
uint32_t as;
|
|
|
|
struct ospf_pce_info *pce = &OspfRI.pce_info;
|
|
|
|
struct listnode *node;
|
|
|
|
struct ri_pce_subtlv_neighbor *neighbor;
|
|
|
|
|
2016-10-25 21:18:50 +02:00
|
|
|
if (!ospf_ri_enabled(vty))
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-10-25 21:18:50 +02:00
|
|
|
|
2018-07-02 17:32:05 +02:00
|
|
|
if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "pce_neighbor: fscanf: %s\n",
|
|
|
|
safe_strerror(errno));
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the domain is not already in the domain list */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
|
|
|
|
if (ntohl(neighbor->header.type) == 0 && as == neighbor->value)
|
2016-10-25 21:18:50 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create new domain if not found */
|
|
|
|
set_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
|
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
2016-10-25 21:18:50 +02:00
|
|
|
return CMD_SUCCESS;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_pce_neighbor,
|
|
|
|
no_pce_neighbor_cmd,
|
2016-09-23 15:47:20 +02:00
|
|
|
"no pce neighbor as (0-65535)",
|
2016-04-19 19:21:17 +02:00
|
|
|
NO_STR
|
|
|
|
PCE_STR
|
|
|
|
"Disable PCE neighbor AS number\n"
|
|
|
|
"AS number of PCE neighbor\n"
|
|
|
|
"AS number in decimal <0-65535>\n")
|
|
|
|
{
|
2016-09-23 22:01:26 +02:00
|
|
|
int idx_number = 4;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
uint32_t as;
|
|
|
|
struct ospf_pce_info *pce = &OspfRI.pce_info;
|
|
|
|
|
2018-07-02 17:32:05 +02:00
|
|
|
if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "no_pce_neighbor: fscanf: %s\n",
|
|
|
|
safe_strerror(errno));
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Unset corresponding PCE domain */
|
|
|
|
unset_pce_neighbor(PCE_DOMAIN_TYPE_AS, as, pce);
|
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (pce_cap_flag,
|
|
|
|
pce_cap_flag_cmd,
|
|
|
|
"pce flag BITPATTERN",
|
|
|
|
PCE_STR
|
|
|
|
"Capabilities of the PCE for path computation\n"
|
|
|
|
"32-bit Hexadecimal value\n")
|
|
|
|
{
|
2016-09-23 22:01:26 +02:00
|
|
|
int idx_bitpattern = 2;
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
uint32_t cap;
|
|
|
|
struct ospf_pce_info *pce = &OspfRI.pce_info;
|
|
|
|
|
2016-10-25 21:18:50 +02:00
|
|
|
if (!ospf_ri_enabled(vty))
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-10-25 21:18:50 +02:00
|
|
|
|
2016-09-23 22:01:26 +02:00
|
|
|
if (sscanf(argv[idx_bitpattern]->arg, "0x%x", &cap) != 1) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "pce_cap_flag: fscanf: %s\n",
|
|
|
|
safe_strerror(errno));
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ntohl(pce->pce_cap_flag.header.type) == 0
|
|
|
|
|| cap != pce->pce_cap_flag.value) {
|
|
|
|
set_pce_cap_flag(cap, pce);
|
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_pce_cap_flag,
|
|
|
|
no_pce_cap_flag_cmd,
|
|
|
|
"no pce flag",
|
|
|
|
NO_STR
|
|
|
|
PCE_STR
|
|
|
|
"Disable PCE capabilities\n")
|
|
|
|
{
|
|
|
|
|
2018-06-14 19:19:44 +02:00
|
|
|
unset_param(&OspfRI.pce_info.pce_cap_flag);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
/* Refresh RI LSA if already engaged */
|
2018-10-26 19:12:41 +02:00
|
|
|
ospf_router_info_schedule(REFRESH_THIS_LSA);
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_ospf_router_info,
|
|
|
|
show_ip_ospf_router_info_cmd,
|
|
|
|
"show ip ospf router-info",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
OSPF_STR
|
|
|
|
"Router Information\n")
|
|
|
|
{
|
|
|
|
|
2017-07-27 16:09:00 +02:00
|
|
|
if (OspfRI.enabled) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "--- Router Information parameters ---\n");
|
2016-04-19 19:21:17 +02:00
|
|
|
show_vty_router_cap(vty, &OspfRI.router_cap.header);
|
|
|
|
} else {
|
|
|
|
if (vty != NULL)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty,
|
|
|
|
" Router Information is disabled on this router\n");
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_opsf_router_info_pce,
|
|
|
|
show_ip_ospf_router_info_pce_cmd,
|
|
|
|
"show ip ospf router-info pce",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
OSPF_STR
|
|
|
|
"Router Information\n"
|
|
|
|
"PCE information\n")
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ospf_pce_info *pce = &OspfRI.pce_info;
|
|
|
|
struct listnode *node;
|
|
|
|
struct ri_pce_subtlv_domain *domain;
|
|
|
|
struct ri_pce_subtlv_neighbor *neighbor;
|
|
|
|
|
2018-01-18 19:11:11 +01:00
|
|
|
if ((OspfRI.enabled) && (OspfRI.pce_info.enabled)) {
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "--- PCE parameters ---\n");
|
2016-04-19 19:21:17 +02:00
|
|
|
|
|
|
|
if (pce->pce_address.header.type != 0)
|
|
|
|
show_vty_pce_subtlv_address(vty,
|
|
|
|
&pce->pce_address.header);
|
|
|
|
|
|
|
|
if (pce->pce_scope.header.type != 0)
|
|
|
|
show_vty_pce_subtlv_path_scope(vty,
|
|
|
|
&pce->pce_scope.header);
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_domain, node, domain)) {
|
|
|
|
if (domain->header.type != 0)
|
|
|
|
show_vty_pce_subtlv_domain(vty,
|
|
|
|
&domain->header);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(pce->pce_neighbor, node, neighbor)) {
|
|
|
|
if (neighbor->header.type != 0)
|
|
|
|
show_vty_pce_subtlv_neighbor(vty,
|
|
|
|
&neighbor->header);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pce->pce_cap_flag.header.type != 0)
|
|
|
|
show_vty_pce_subtlv_cap_flag(vty,
|
|
|
|
&pce->pce_cap_flag.header);
|
|
|
|
|
|
|
|
} else {
|
2018-01-18 19:11:11 +01:00
|
|
|
vty_out(vty, " PCE info is disabled on this router\n");
|
2016-04-19 19:21:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install new CLI commands */
|
|
|
|
static void ospf_router_info_register_vty(void)
|
|
|
|
{
|
|
|
|
install_element(VIEW_NODE, &show_ip_ospf_router_info_cmd);
|
|
|
|
install_element(VIEW_NODE, &show_ip_ospf_router_info_pce_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
install_element(OSPF_NODE, &router_info_area_cmd);
|
|
|
|
install_element(OSPF_NODE, &no_router_info_cmd);
|
|
|
|
install_element(OSPF_NODE, &pce_address_cmd);
|
2016-10-26 14:11:12 +02:00
|
|
|
install_element(OSPF_NODE, &no_pce_address_cmd);
|
2016-04-19 19:21:17 +02:00
|
|
|
install_element(OSPF_NODE, &pce_path_scope_cmd);
|
2016-10-26 14:11:12 +02:00
|
|
|
install_element(OSPF_NODE, &no_pce_path_scope_cmd);
|
2016-04-19 19:21:17 +02:00
|
|
|
install_element(OSPF_NODE, &pce_domain_cmd);
|
|
|
|
install_element(OSPF_NODE, &no_pce_domain_cmd);
|
|
|
|
install_element(OSPF_NODE, &pce_neighbor_cmd);
|
|
|
|
install_element(OSPF_NODE, &no_pce_neighbor_cmd);
|
|
|
|
install_element(OSPF_NODE, &pce_cap_flag_cmd);
|
2016-12-05 20:28:24 +01:00
|
|
|
install_element(OSPF_NODE, &no_pce_cap_flag_cmd);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-04-19 19:21:17 +02:00
|
|
|
return;
|
|
|
|
}
|