isisd: Update TLVs processing for TE, RI & SR

In preparation to Segment Routing:
 - Update the management of Traffic Engineering subTLVs to the new tlvs parser
 - Add Router Capability TLV 242 as per RFC 4971 & 7981
 - Add Segment Routing subTLVs as per draft-isis-segment-routing-extension-25

Modified files:
 - isis_tlvs.h: add new structure to manage TE subTLVs, TLV 242 & SR subTLVs
 - isis_tlvs.c: add new functions (pack, copy, free, unpack & print) to process
   TE subTLVs, Router Capability TLV and SR subTLVs
 - isis_circuit.[c,h] & isis_lsp.[c,h]: update to new subTLVs & TLV processing
 - isis_te.[c,h]: remove all old TE structures and managment functions,
   and add hook call to set local and remote IP addresses as wellas update TE
   parameters
 - isis_zebra.[c,h]: add hook call when new interface is up
 - isis_mt.[c,h], isis_pdu.c & isis_northbound.c: adjust to new TE subTLVs
 - tests/isisd/test_fuzz_isis_tlv_tests.h.gz: adapte fuuz tests to new parser

Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
This commit is contained in:
Olivier Dugeon 2019-07-26 16:07:39 +02:00
parent 215e03fe53
commit 1b3f47d04c
15 changed files with 1638 additions and 1355 deletions

View File

@ -135,8 +135,6 @@ struct isis_circuit *isis_circuit_new(void)
}
#endif /* ifndef FABRICD */
circuit->mtc = mpls_te_circuit_new();
circuit_mt_init(circuit);
QOBJ_REG(circuit, isis_circuit);
@ -266,8 +264,11 @@ void isis_circuit_add_addr(struct isis_circuit *circuit,
ipv4->prefix = connected->address->u.prefix4;
listnode_add(circuit->ip_addrs, ipv4);
/* Update MPLS TE Local IP address parameter */
set_circuitparams_local_ipaddr(circuit->mtc, ipv4->prefix);
/* Update Local IP address parameter if MPLS TE is enable */
if (circuit->ext && IS_MPLS_TE(circuit->ext)) {
circuit->ext->local_addr.s_addr = ipv4->prefix.s_addr;
SET_SUBTLV(circuit->ext, EXT_LOCAL_ADDR);
}
if (circuit->area)
lsp_regenerate_schedule(circuit->area, circuit->is_type,
@ -478,6 +479,7 @@ void isis_circuit_if_add(struct isis_circuit *circuit, struct interface *ifp)
for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, conn))
isis_circuit_add_addr(circuit, conn);
}
void isis_circuit_if_del(struct isis_circuit *circuit, struct interface *ifp)
@ -521,7 +523,6 @@ void isis_circuit_if_bind(struct isis_circuit *circuit, struct interface *ifp)
assert(ifp->info == circuit);
else
ifp->info = circuit;
isis_link_params_update(circuit, ifp);
}
void isis_circuit_if_unbind(struct isis_circuit *circuit, struct interface *ifp)

View File

@ -121,7 +121,7 @@ struct isis_circuit {
uint16_t psnp_interval[2]; /* psnp-interval in seconds */
uint8_t metric[2];
uint32_t te_metric[2];
struct mpls_te_circuit *mtc; /* MPLS-TE parameters */
struct isis_ext_subtlvs *ext; /* Extended parameters (TE + Adj SID */
int ip_router; /* Route IP ? */
int is_passive; /* Is Passive ? */
struct list *mt_settings; /* IS-IS MT Settings */

View File

@ -52,9 +52,9 @@
#include "isisd/isis_csm.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_te.h"
#include "isisd/isis_mt.h"
#include "isisd/isis_tlvs.h"
#include "isisd/isis_te.h"
#include "isisd/fabricd.h"
#include "isisd/isis_tx_queue.h"
@ -781,8 +781,8 @@ static void lsp_build_ext_reach_ipv6(struct isis_lsp *lsp,
if (!rn->info)
continue;
struct isis_ext_info *info = rn->info;
struct prefix_ipv6 *p, *src_p;
srcdest_rnode_prefixes(rn, (const struct prefix **)&p,
(const struct prefix **)&src_p);
@ -863,6 +863,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
/* Protocols Supported */
if (area->ip_circuits > 0 || area->ipv6_circuits > 0) {
struct nlpids nlpids = {.count = 0};
if (area->ip_circuits > 0) {
lsp_debug(
"ISIS (%s): Found IPv4 circuit, adding IPv4 to NLPIDs",
@ -908,10 +909,12 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
area->area_tag);
}
/* IPv4 address and TE router ID TLVs. In case of the first one we don't
* follow "C" vendor, but "J" vendor behavior - one IPv4 address is put
* into
* LSP and this address is same as router id. */
/* IPv4 address and TE router ID TLVs.
* In case of the first one we don't follow "C" vendor,
* but "J" vendor behavior - one IPv4 address is put
* into LSP. TE router ID will be the same if MPLS-TE
* is not activate or MPLS-TE router-id not specified
*/
if (isis->router_id != 0) {
struct in_addr id = {.s_addr = isis->router_id};
inet_ntop(AF_INET, &id, buf, sizeof(buf));
@ -919,11 +922,14 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
area->area_tag, buf);
isis_tlvs_add_ipv4_address(lsp->tlvs, &id);
/* Exactly same data is put into TE router ID TLV, but only if
* new style
* TLV's are in use. */
/* If new style TLV's are in use, add TE router ID TLV
* Check if MPLS-TE is activate and mpls-te router-id set
* otherwise add exactly same data as for IPv4 address
*/
if (area->newmetric) {
if (IS_MPLS_TE(area->mta)
&& area->mta->router_id.s_addr != 0)
id.s_addr = area->mta->router_id.s_addr;
lsp_debug(
"ISIS (%s): Adding router ID also as TE router ID tlv.",
area->area_tag);
@ -1004,6 +1010,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
&& circuit->ipv6_non_link->count > 0) {
struct listnode *ipnode;
struct prefix_ipv6 *ipv6;
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link,
ipnode, ipv6)) {
lsp_debug(
@ -1036,25 +1043,10 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
lsp->tlvs, ne_id,
metric);
}
if (area->newmetric) {
uint8_t subtlvs[256];
uint8_t subtlv_len;
if (IS_MPLS_TE(area->mta)
&& circuit->interface
&& HAS_LINK_PARAMS(
circuit->interface))
subtlv_len = add_te_subtlvs(
subtlvs,
circuit->mtc);
else
subtlv_len = 0;
if (area->newmetric)
tlvs_add_mt_bcast(
lsp->tlvs, circuit,
level, ne_id, metric,
subtlvs, subtlv_len);
}
level, ne_id, metric);
}
} else {
lsp_debug(
@ -1079,36 +1071,6 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
lsp->tlvs, ne_id, metric);
}
if (area->newmetric) {
uint8_t subtlvs[256];
uint8_t subtlv_len;
if (IS_MPLS_TE(area->mta)
&& circuit->interface != NULL
&& HAS_LINK_PARAMS(
circuit->interface))
/* Update Local and Remote IP
* address for MPLS TE circuit
* parameters */
/* NOTE sure that it is the
* pertinent place for that
* updates */
/* Local IP address could be
* updated in isis_circuit.c -
* isis_circuit_add_addr() */
/* But, where update remote IP
* address ? in isis_pdu.c -
* process_p2p_hello() ? */
/* Add SubTLVs & Adjust real
* size of SubTLVs */
subtlv_len = add_te_subtlvs(
subtlvs, circuit->mtc);
else
/* Or keep only TE metric with
* no SubTLVs if MPLS_TE is off
*/
subtlv_len = 0;
uint32_t neighbor_metric;
if (fabricd_tier(area) == 0) {
neighbor_metric = 0xffe;
@ -1117,8 +1079,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
}
tlvs_add_mt_p2p(lsp->tlvs, circuit,
ne_id, neighbor_metric,
subtlvs, subtlv_len);
ne_id, neighbor_metric);
}
} else {
lsp_debug(
@ -1512,7 +1473,7 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
}
if (circuit->area->newmetric) {
isis_tlvs_add_extended_reach(lsp->tlvs, ISIS_MT_IPV4_UNICAST,
ne_id, 0, NULL, 0);
ne_id, 0, circuit->ext);
lsp_debug(
"ISIS (%s): Adding %s.%02x as te-style neighbor (self)",
area->area_tag, sysid_print(ne_id),
@ -1554,7 +1515,7 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
if (circuit->area->newmetric) {
isis_tlvs_add_extended_reach(lsp->tlvs,
ISIS_MT_IPV4_UNICAST,
ne_id, 0, NULL, 0);
ne_id, 0, circuit->ext);
lsp_debug(
"ISIS (%s): Adding %s.%02x as te-style neighbor (peer)",
area->area_tag, sysid_print(ne_id),

View File

@ -511,8 +511,8 @@ static uint16_t *circuit_bcast_mt_set(struct isis_circuit *circuit, int level,
static void tlvs_add_mt_set(struct isis_area *area, struct isis_tlvs *tlvs,
unsigned int mt_count, uint16_t *mt_set,
uint8_t *id, uint32_t metric, uint8_t *subtlvs,
uint8_t subtlv_len)
uint8_t *id, uint32_t metric,
struct isis_ext_subtlvs *ext)
{
for (unsigned int i = 0; i < mt_count; i++) {
uint16_t mtid = mt_set[i];
@ -527,30 +527,27 @@ static void tlvs_add_mt_set(struct isis_area *area, struct isis_tlvs *tlvs,
area->area_tag, sysid_print(id),
LSP_PSEUDO_ID(id), isis_mtid2str(mtid));
}
isis_tlvs_add_extended_reach(tlvs, mtid, id, metric, subtlvs,
subtlv_len);
isis_tlvs_add_extended_reach(tlvs, mtid, id, metric, ext);
}
}
void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
int level, uint8_t *id, uint32_t metric,
uint8_t *subtlvs, uint8_t subtlv_len)
int level, uint8_t *id, uint32_t metric)
{
unsigned int mt_count;
uint16_t *mt_set = circuit_bcast_mt_set(circuit, level, &mt_count);
tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, id, metric,
subtlvs, subtlv_len);
circuit->ext);
}
void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
uint8_t *id, uint32_t metric, uint8_t *subtlvs,
uint8_t subtlv_len)
uint8_t *id, uint32_t metric)
{
struct isis_adjacency *adj = circuit->u.p2p.neighbor;
tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, id,
metric, subtlvs, subtlv_len);
metric, circuit->ext);
}
void mt_init(void)

View File

@ -116,10 +116,8 @@ bool tlvs_to_adj_mt_set(struct isis_tlvs *tlvs, bool v4_usable, bool v6_usable,
bool adj_has_mt(struct isis_adjacency *adj, uint16_t mtid);
void adj_mt_finish(struct isis_adjacency *adj);
void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
int level, uint8_t *id, uint32_t metric,
uint8_t *subtlvs, uint8_t subtlv_len);
int level, uint8_t *id, uint32_t metric);
void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
uint8_t *id, uint32_t metric, uint8_t *subtlvs,
uint8_t subtlv_len);
uint8_t *id, uint32_t metric);
void mt_init(void);
#endif

View File

@ -1384,7 +1384,7 @@ static int isis_instance_mpls_te_create(enum nb_event event,
struct mpls_te_area *new;
zlog_debug("ISIS MPLS-TE: Initialize area %s",
zlog_debug("ISIS-TE(%s): Initialize MPLS Traffic Engineering",
area->area_tag);
new = XCALLOC(MTYPE_ISIS_MPLS_TE, sizeof(struct mpls_te_area));
@ -1410,12 +1410,12 @@ static int isis_instance_mpls_te_create(enum nb_event event,
* 2) MPLS-TE was once enabled then disabled, and now enabled again.
*/
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
if (circuit->mtc == NULL || IS_FLOOD_AS(circuit->mtc->type))
if (circuit->ext == NULL)
continue;
if (!IS_MPLS_TE(circuit->mtc)
if (!IS_EXT_TE(circuit->ext)
&& HAS_LINK_PARAMS(circuit->interface))
circuit->mtc->status = enable;
isis_link_params_update(circuit, circuit->interface);
else
continue;
@ -1446,11 +1446,16 @@ static int isis_instance_mpls_te_destroy(enum nb_event event,
/* Flush LSP if circuit engage */
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
if (circuit->mtc == NULL || (circuit->mtc->status == disable))
if (!IS_EXT_TE(circuit->ext))
continue;
/* disable MPLS_TE Circuit */
circuit->mtc->status = disable;
/* disable MPLS_TE Circuit keeping SR one's */
if (IS_SUBTLV(circuit->ext, EXT_ADJ_SID))
circuit->ext->status = EXT_ADJ_SID;
else if (IS_SUBTLV(circuit->ext, EXT_LAN_ADJ_SID))
circuit->ext->status = EXT_LAN_ADJ_SID;
else
circuit->ext->status = 0;
/* Re-originate circuit without STD_TE & GMPLS parameters */
if (circuit->area)
@ -1458,6 +1463,9 @@ static int isis_instance_mpls_te_destroy(enum nb_event event,
0);
}
zlog_debug("ISIS-TE(%s): Disabled MPLS Traffic Engineering",
area->area_tag);
return NB_OK;
}

View File

@ -199,13 +199,6 @@ static int process_p2p_hello(struct iih_info *iih)
changed |= tlvs_to_adj_mt_set(iih->tlvs, iih->v4_usable, iih->v6_usable,
adj);
/* Update MPLS TE Remote IP address parameter if possible */
if (IS_MPLS_TE(iih->circuit->area->mta)
&& IS_MPLS_TE(iih->circuit->mtc)
&& adj->ipv4_address_count)
set_circuitparams_rmt_ipaddr(iih->circuit->mtc,
adj->ipv4_addresses[0]);
/* lets take care of the expiry */
THREAD_TIMER_OFF(adj->t_expire);
thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,9 @@
*
* This is an implementation of RFC5305, RFC 5307 and RFC 7810
*
* Copyright (C) 2014 Orange Labs
* http://www.orange.com
* Author: Olivier Dugeon <olivier.dugeon@orange.com>
*
* Copyright (C) 2014 - 2019 Orange Labs http://www.orange.com
*
* This file is part of GNU Zebra.
*
@ -50,10 +51,10 @@
* Remote AS number 24 RFC5316
* IPv4 Remote ASBR identifier 25 RFC5316
*
* NOTE: RFC5316 is not fully supported in this version
* only subTLVs decoding is provided
*/
/* NOTE: RFC5316 is not yet supported in this version */
/* Following define the type of TE link regarding the various RFC */
#define STD_TE 0x01
#define GMPLS 0x02
@ -73,170 +74,9 @@
#define IS_INTER_AS_AS(x) (x & INTER_AS & FLOOD_AS)
/*
* Following section defines subTLV (tag, length, value) structures,
* used for Traffic Engineering.
* Note (since release 7.2), subTLVs definition, serialization
* and de-serialization have mode to isis_tlvs.[c,h]
*/
struct subtlv_header {
uint8_t type; /* sub_TLV_XXX type (see above) */
uint8_t length; /* Value portion only, in byte */
};
#define MAX_SUBTLV_SIZE 256
#define SUBTLV_HDR_SIZE 2 /* (sizeof (struct sub_tlv_header)) */
#define SUBTLV_SIZE(stlvh) (SUBTLV_HDR_SIZE + (stlvh)->length)
#define SUBTLV_HDR_TOP(lsph) (struct subtlv_header *)((char *)(lsph) + ISIS_LSP_HEADER_SIZE)
#define SUBTLV_HDR_NEXT(stlvh) (struct subtlv_header *)((char *)(stlvh) + SUBTLV_SIZE(stlvh))
#define SUBTLV_TYPE(stlvh) stlvh.header.type
#define SUBTLV_LEN(stlvh) stlvh.header.length
#define SUBTLV_VAL(stlvh) stlvh.value
#define SUBTLV_DATA(stlvh) stlvh + SUBTLV_HDR_SIZE
#define SUBTLV_DEF_SIZE 4
/* Link Sub-TLV: Resource Class/Color - RFC 5305 */
#define TE_SUBTLV_ADMIN_GRP 3
struct te_subtlv_admin_grp {
struct subtlv_header header; /* Value length is 4 octets. */
uint32_t value; /* Admin. group membership. */
} __attribute__((__packed__));
/* Link Local/Remote Identifiers - RFC 5307 */
#define TE_SUBTLV_LLRI 4
#define TE_SUBTLV_LLRI_SIZE 8
struct te_subtlv_llri {
struct subtlv_header header; /* Value length is 8 octets. */
uint32_t local; /* Link Local Identifier */
uint32_t remote; /* Link Remote Identifier */
} __attribute__((__packed__));
/* Link Sub-TLV: Local Interface IP Address - RFC 5305 */
#define TE_SUBTLV_LOCAL_IPADDR 6
struct te_subtlv_local_ipaddr {
struct subtlv_header header; /* Value length is 4 x N octets. */
struct in_addr value; /* Local IP address(es). */
} __attribute__((__packed__));
/* Link Sub-TLV: Neighbor Interface IP Address - RFC 5305 */
#define TE_SUBTLV_RMT_IPADDR 8
struct te_subtlv_rmt_ipaddr {
struct subtlv_header header; /* Value length is 4 x N octets. */
struct in_addr value; /* Neighbor's IP address(es). */
} __attribute__((__packed__));
/* Link Sub-TLV: Maximum Bandwidth - RFC 5305 */
#define TE_SUBTLV_MAX_BW 9
struct te_subtlv_max_bw {
struct subtlv_header header; /* Value length is 4 octets. */
float value; /* bytes/sec */
} __attribute__((__packed__));
/* Link Sub-TLV: Maximum Reservable Bandwidth - RFC 5305 */
#define TE_SUBTLV_MAX_RSV_BW 10
struct te_subtlv_max_rsv_bw {
struct subtlv_header header; /* Value length is 4 octets. */
float value; /* bytes/sec */
} __attribute__((__packed__));
/* Link Sub-TLV: Unreserved Bandwidth - RFC 5305 */
#define TE_SUBTLV_UNRSV_BW 11
#define TE_SUBTLV_UNRSV_SIZE 32
struct te_subtlv_unrsv_bw {
struct subtlv_header header; /* Value length is 32 octets. */
float value[8]; /* One for each priority level. */
} __attribute__((__packed__));
/* Link Sub-TLV: Traffic Engineering Metric - RFC 5305 */
#define TE_SUBTLV_TE_METRIC 18
#define TE_SUBTLV_TE_METRIC_SIZE 3
struct te_subtlv_te_metric {
struct subtlv_header header; /* Value length is 4 octets. */
uint8_t value[3]; /* Link metric for TE purpose. */
} __attribute__((__packed__));
/* Remote AS Number sub-TLV - RFC5316 */
#define TE_SUBTLV_RAS 24
struct te_subtlv_ras {
struct subtlv_header header; /* Value length is 4 octets. */
uint32_t value; /* Remote AS number */
} __attribute__((__packed__));
/* IPv4 Remote ASBR ID Sub-TLV - RFC5316 */
#define TE_SUBTLV_RIP 25
struct te_subtlv_rip {
struct subtlv_header header; /* Value length is 4 octets. */
struct in_addr value; /* Remote ASBR IP address */
} __attribute__((__packed__));
/* TE Metric Extensions - RFC 7810 */
/* Link Sub-TLV: Average Link Delay */
#define TE_SUBTLV_AV_DELAY 33
struct te_subtlv_av_delay {
struct subtlv_header header; /* Value length is 4 bytes. */
uint32_t value; /* Average delay in micro-seconds only 24 bits => 0 ...
16777215
with Anomalous Bit (A) as Upper most bit */
} __attribute__((__packed__));
/* Link Sub-TLV: Low/High Link Delay */
#define TE_SUBTLV_MM_DELAY 34
#define TE_SUBTLV_MM_DELAY_SIZE 8
struct te_subtlv_mm_delay {
struct subtlv_header header; /* Value length is 8 bytes. */
uint32_t low; /* low delay in micro-seconds only 24 bits => 0 ...
16777215
with Anomalous Bit (A) as Upper most bit */
uint32_t high; /* high delay in micro-seconds only 24 bits => 0 ...
16777215 */
} __attribute__((__packed__));
/* Link Sub-TLV: Link Delay Variation i.e. Jitter */
#define TE_SUBTLV_DELAY_VAR 35
struct te_subtlv_delay_var {
struct subtlv_header header; /* Value length is 4 bytes. */
uint32_t value; /* interval in micro-seconds only 24 bits => 0 ...
16777215 */
} __attribute__((__packed__));
/* Link Sub-TLV: Routine Unidirectional Link Packet Loss */
#define TE_SUBTLV_PKT_LOSS 36
struct te_subtlv_pkt_loss {
struct subtlv_header header; /* Value length is 4 bytes. */
uint32_t
value; /* in percentage of total traffic only 24 bits (2^24 - 2)
with Anomalous Bit (A) as Upper most bit */
} __attribute__((__packed__));
/* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */
#define TE_SUBTLV_RES_BW 37
struct te_subtlv_res_bw {
struct subtlv_header header; /* Value length is 4 bytes. */
float value; /* bandwidth in IEEE floating point format with units in
bytes per second */
} __attribute__((__packed__));
/* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */
#define TE_SUBTLV_AVA_BW 38
struct te_subtlv_ava_bw {
struct subtlv_header header; /* Value length is 4 octets. */
float value; /* bandwidth in IEEE floating point format with units in
bytes per second */
} __attribute__((__packed__));
/* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */
#define TE_SUBTLV_USE_BW 39
struct te_subtlv_use_bw {
struct subtlv_header header; /* Value length is 4 octets. */
float value; /* bandwidth in IEEE floating point format with units in
bytes per second */
} __attribute__((__packed__));
#define TE_SUBTLV_MAX 40 /* Last SUBTLV + 1 */
/* Following declaration concerns the MPLS-TE and LINk-TE management */
typedef enum _status_t { disable, enable, learn } status_t;
@ -244,7 +84,10 @@ typedef enum _status_t { disable, enable, learn } status_t;
/* Mode for Inter-AS LSP */ /* TODO: Check how if LSP is flooded in RFC5316 */
typedef enum _interas_mode_t { off, region, as, emulate } interas_mode_t;
#define IS_MPLS_TE(m) (m && m->status == enable)
#define IS_EXT_TE(e) (e && e->status != 0 \
&& e->status != EXT_ADJ_SID \
&& e->status != EXT_LAN_ADJ_SID)
#define IS_MPLS_TE(a) (a && a->status == enable)
/* Per area MPLS-TE parameters */
struct mpls_te_area {
@ -262,56 +105,9 @@ struct mpls_te_area {
struct in_addr router_id;
};
/* Per Circuit MPLS-TE parameters */
struct mpls_te_circuit {
/* Status of MPLS-TE on this interface */
status_t status;
/* Type of MPLS-TE circuit: STD_TE(RFC5305), INTER_AS(RFC5316),
* INTER_AS_EMU(RFC5316 emulated) */
uint8_t type;
/* Total size of sub_tlvs */
uint8_t length;
/* Store subTLV in network byte order. */
/* RFC5305 */
struct te_subtlv_admin_grp admin_grp;
/* RFC5307 */
struct te_subtlv_llri llri;
/* RFC5305 */
struct te_subtlv_local_ipaddr local_ipaddr;
struct te_subtlv_rmt_ipaddr rmt_ipaddr;
struct te_subtlv_max_bw max_bw;
struct te_subtlv_max_rsv_bw max_rsv_bw;
struct te_subtlv_unrsv_bw unrsv_bw;
struct te_subtlv_te_metric te_metric;
/* RFC5316 */
struct te_subtlv_ras ras;
struct te_subtlv_rip rip;
/* RFC7810 */
struct te_subtlv_av_delay av_delay;
struct te_subtlv_mm_delay mm_delay;
struct te_subtlv_delay_var delay_var;
struct te_subtlv_pkt_loss pkt_loss;
struct te_subtlv_res_bw res_bw;
struct te_subtlv_ava_bw ava_bw;
struct te_subtlv_use_bw use_bw;
};
/* Prototypes. */
void isis_mpls_te_init(void);
struct mpls_te_circuit *mpls_te_circuit_new(void);
struct sbuf;
void mpls_te_print_detail(struct sbuf *buf, int indent, uint8_t *subtlvs,
uint8_t subtlv_len);
void set_circuitparams_local_ipaddr(struct mpls_te_circuit *, struct in_addr);
void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit *, struct in_addr);
uint8_t subtlvs_len(struct mpls_te_circuit *);
uint8_t add_te_subtlvs(uint8_t *, struct mpls_te_circuit *);
uint8_t build_te_subtlvs(uint8_t *, struct isis_circuit *);
void isis_link_params_update(struct isis_circuit *, struct interface *);
void isis_mpls_te_update(struct interface *);
int isis_mpls_te_update(struct interface *);
#endif /* _ZEBRA_ISIS_MPLS_TE_H */

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,8 @@
* IS-IS TLV Serializer/Deserializer
*
* Copyright (C) 2015,2017 Christian Franke
* Copyright (C) 2019 Olivier Dugeon - Orange Labs (for TE and SR)
*
* This file is part of FRR.
*
@ -66,14 +68,14 @@ struct isis_lsp_entry {
};
struct isis_extended_reach;
struct isis_ext_subtlvs;
struct isis_extended_reach {
struct isis_extended_reach *next;
uint8_t id[7];
uint32_t metric;
uint8_t *subtlvs;
uint8_t subtlv_len;
struct isis_ext_subtlvs *subtlvs;
};
struct isis_extended_ip_reach;
@ -130,6 +132,95 @@ struct isis_threeway_adj {
uint32_t neighbor_circuit_id;
};
/*
* Segment Routing subTLV's as per
* draft-ietf-isis-segment-routing-extension-25
*/
#define ISIS_SUBTLV_SRGB_FLAG_I 0x80
#define ISIS_SUBTLV_SRGB_FLAG_V 0x40
#define IS_SR_IPV4(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_I)
#define IS_SR_IPV6(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_V)
/* Structure aggregating SRGB info */
struct isis_srgb {
uint8_t flags;
uint32_t range_size;
uint32_t lower_bound;
};
/* Prefix-SID sub-TLVs flags */
#define ISIS_PREFIX_SID_READVERTISED 0x80
#define ISIS_PREFIX_SID_NODE 0x40
#define ISIS_PREFIX_SID_NO_PHP 0x20
#define ISIS_PREFIX_SID_EXPLICIT_NULL 0x10
#define ISIS_PREFIX_SID_VALUE 0x08
#define ISIS_PREFIX_SID_LOCAL 0x04
struct isis_prefix_sid;
struct isis_prefix_sid {
struct isis_prefix_sid *next;
uint8_t flags;
uint8_t algorithm;
uint32_t value;
};
/* Adj-SID and LAN-Ajd-SID sub-TLVs flags */
#define EXT_SUBTLV_LINK_ADJ_SID_FFLG 0x80
#define EXT_SUBTLV_LINK_ADJ_SID_BFLG 0x40
#define EXT_SUBTLV_LINK_ADJ_SID_VFLG 0x20
#define EXT_SUBTLV_LINK_ADJ_SID_LFLG 0x10
#define EXT_SUBTLV_LINK_ADJ_SID_SFLG 0x08
#define EXT_SUBTLV_LINK_ADJ_SID_PFLG 0x04
struct isis_adj_sid;
struct isis_adj_sid {
struct isis_adj_sid *next;
uint8_t family;
uint8_t flags;
uint8_t weight;
uint32_t sid;
};
struct isis_lan_adj_sid;
struct isis_lan_adj_sid {
struct isis_lan_adj_sid *next;
uint8_t family;
uint8_t flags;
uint8_t weight;
uint8_t neighbor_id[ISIS_SYS_ID_LEN];
uint32_t sid;
};
/* RFC 4971 & RFC 7981 */
#define ISIS_ROUTER_CAP_FLAG_S 0x01
#define ISIS_ROUTER_CAP_FLAG_D 0x02
#define ISIS_ROUTER_CAP_SIZE 5
/* Number of supported algorithm for Segment Routing.
* Right now only 2 have been standardized:
* - 0: SPF
* - 1: Strict SPF
*/
#define SR_ALGORITHM_COUNT 2
#define SR_ALGORITHM_SPF 0
#define SR_ALGORITHM_STRICT_SPF 1
#define SR_ALGORITHM_UNSET 255
struct isis_router_cap {
struct in_addr router_id;
uint8_t flags;
/* draft-ietf-segment-routing-extensions-25 */
struct isis_srgb srgb;
uint8_t algo[SR_ALGORITHM_COUNT];
/* RFC 8491 */
#define MSD_TYPE_BASE_MPLS_IMPOSITION 0x01
uint8_t msd;
};
struct isis_item;
struct isis_item {
struct isis_item *next;
@ -233,26 +324,10 @@ struct isis_tlvs {
struct isis_item_list ipv6_reach;
struct isis_mt_item_list mt_ipv6_reach;
struct isis_threeway_adj *threeway_adj;
struct isis_router_cap *router_cap;
struct isis_spine_leaf *spine_leaf;
};
#define ISIS_PREFIX_SID_READVERTISED 0x80
#define ISIS_PREFIX_SID_NODE 0x40
#define ISIS_PREFIX_SID_NO_PHP 0x20
#define ISIS_PREFIX_SID_EXPLICIT_NULL 0x10
#define ISIS_PREFIX_SID_VALUE 0x08
#define ISIS_PREFIX_SID_LOCAL 0x04
struct isis_prefix_sid;
struct isis_prefix_sid {
struct isis_prefix_sid *next;
uint8_t flags;
uint8_t algorithm;
uint32_t value;
};
enum isis_tlv_context {
ISIS_CONTEXT_LSP,
ISIS_CONTEXT_SUBTLV_NE_REACH,
@ -266,11 +341,12 @@ struct isis_subtlvs {
/* draft-baker-ipv6-isis-dst-src-routing-06 */
struct prefix_ipv6 *source_prefix;
/* draft-ietf-isis-segment-routing-extensions-16 */
/* draft-ietf-isis-segment-routing-extensions-25 */
struct isis_item_list prefix_sids;
};
enum isis_tlv_type {
/* TLVs code point */
ISIS_TLV_AREA_ADDRESSES = 1,
ISIS_TLV_OLDSTYLE_REACH = 2,
ISIS_TLV_LAN_NEIGHBORS = 6,
@ -295,10 +371,149 @@ enum isis_tlv_type {
ISIS_TLV_IPV6_REACH = 236,
ISIS_TLV_MT_IPV6_REACH = 237,
ISIS_TLV_THREE_WAY_ADJ = 240,
ISIS_TLV_ROUTER_CAPABILITY = 242,
ISIS_TLV_MAX = 256,
/* subTLVs code point */
ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22,
/* RFC 5305 & RFC 6119 */
ISIS_SUBTLV_ADMIN_GRP = 3,
ISIS_SUBTLV_LOCAL_IPADDR = 6,
ISIS_SUBTLV_RMT_IPADDR = 8,
ISIS_SUBTLV_MAX_BW = 9,
ISIS_SUBTLV_MAX_RSV_BW = 10,
ISIS_SUBTLV_UNRSV_BW = 11,
ISIS_SUBTLV_LOCAL_IPADDR6 = 12,
ISIS_SUBTLV_RMT_IPADDR6 = 13,
ISIS_SUBTLV_TE_METRIC = 18,
/* RFC 5307 */
ISIS_SUBTLV_LLRI = 4,
/* RFC 5316 */
ISIS_SUBTLV_RAS = 24,
ISIS_SUBTLV_RIP = 25,
/* draft-isis-segment-routing-extension-25 */
ISIS_SUBTLV_SID_LABEL = 1,
ISIS_SUBTLV_SID_LABEL_RANGE = 2,
ISIS_SUBTLV_ALGORITHM = 19,
ISIS_SUBTLV_NODE_MSD = 23,
ISIS_SUBTLV_PREFIX_SID = 3,
ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22
ISIS_SUBTLV_ADJ_SID = 31,
ISIS_SUBTLV_LAN_ADJ_SID = 32,
/* RFC 7810 */
ISIS_SUBTLV_AV_DELAY = 33,
ISIS_SUBTLV_MM_DELAY = 34,
ISIS_SUBTLV_DELAY_VAR = 35,
ISIS_SUBTLV_PKT_LOSS = 36,
ISIS_SUBTLV_RES_BW = 37,
ISIS_SUBTLV_AVA_BW = 38,
ISIS_SUBTLV_USE_BW = 39,
ISIS_SUBTLV_MAX = 40
};
/* subTLVs size for TE and SR */
enum ext_subtlv_size {
ISIS_SUBTLV_LLRI_SIZE = 8,
ISIS_SUBTLV_UNRSV_BW_SIZE = 32,
ISIS_SUBTLV_TE_METRIC_SIZE = 3,
ISIS_SUBTLV_IPV6_ADDR_SIZE = 16,
/* draft-isis-segment-routing-extension-25 */
ISIS_SUBTLV_SID_LABEL_SIZE = 3,
ISIS_SUBTLV_SID_LABEL_RANGE_SIZE = 9,
ISIS_SUBTLV_ALGORITHM_SIZE = 4,
ISIS_SUBTLV_NODE_MSD_SIZE = 2,
ISIS_SUBTLV_ADJ_SID_SIZE = 5,
ISIS_SUBTLV_LAN_ADJ_SID_SIZE = 11,
ISIS_SUBTLV_PREFIX_SID_SIZE = 5,
ISIS_SUBTLV_MM_DELAY_SIZE = 8,
ISIS_SUBTLV_HDR_SIZE = 2,
ISIS_SUBTLV_DEF_SIZE = 4,
ISIS_SUBTLV_MAX_SIZE = 180
};
/* Macros to manage the optional presence of EXT subTLVs */
#define SET_SUBTLV(s, t) ((s->status) |= (t))
#define UNSET_SUBTLV(s, t) ((s->status) &= ~(t))
#define IS_SUBTLV(s, t) (s->status & t)
#define EXT_DISABLE 0x000000
#define EXT_ADM_GRP 0x000001
#define EXT_LLRI 0x000002
#define EXT_LOCAL_ADDR 0x000004
#define EXT_NEIGH_ADDR 0x000008
#define EXT_LOCAL_ADDR6 0x000010
#define EXT_NEIGH_ADDR6 0x000020
#define EXT_MAX_BW 0x000040
#define EXT_MAX_RSV_BW 0x000080
#define EXT_UNRSV_BW 0x000100
#define EXT_TE_METRIC 0x000200
#define EXT_RMT_AS 0x000400
#define EXT_RMT_IP 0x000800
#define EXT_ADJ_SID 0x001000
#define EXT_LAN_ADJ_SID 0x002000
#define EXT_DELAY 0x004000
#define EXT_MM_DELAY 0x008000
#define EXT_DELAY_VAR 0x010000
#define EXT_PKT_LOSS 0x020000
#define EXT_RES_BW 0x040000
#define EXT_AVA_BW 0x080000
#define EXT_USE_BW 0x100000
/*
* This structure groups all Extended IS Reachability subTLVs.
*
* Each bit of the status field indicates if a subTLVs is valid or not.
* SubTLVs values use following units:
* - Bandwidth in bytes/sec following IEEE format,
* - Delay in micro-seconds with only 24 bits significant
* - Packet Loss in percentage of total traffic with only 24 bits (2^24 - 2)
*
* For Delay and packet Loss, upper bit (A) indicates if the value is
* normal (0) or anomalous (1).
*/
#define IS_ANORMAL(v) (v & 0x80000000)
struct isis_ext_subtlvs {
uint32_t status;
uint32_t adm_group; /* Resource Class/Color - RFC 5305 */
/* Link Local/Remote Identifiers - RFC 5307 */
uint32_t local_llri;
uint32_t remote_llri;
struct in_addr local_addr; /* Local IP Address - RFC 5305 */
struct in_addr neigh_addr; /* Neighbor IP Address - RFC 5305 */
struct in6_addr local_addr6; /* Local IPv6 Address - RFC 6119 */
struct in6_addr neigh_addr6; /* Neighbor IPv6 Address - RFC 6119 */
float max_bw; /* Maximum Bandwidth - RFC 5305 */
float max_rsv_bw; /* Maximum Reservable Bandwidth - RFC 5305 */
float unrsv_bw[8]; /* Unreserved Bandwidth - RFC 5305 */
uint32_t te_metric; /* Traffic Engineering Metric - RFC 5305 */
uint32_t remote_as; /* Remote AS Number sub-TLV - RFC5316 */
struct in_addr remote_ip; /* IPv4 Remote ASBR ID Sub-TLV - RFC5316 */
uint32_t delay; /* Average Link Delay - RFC 8570 */
uint32_t min_delay; /* Low Link Delay - RFC 8570 */
uint32_t max_delay; /* High Link Delay - RFC 8570 */
uint32_t delay_var; /* Link Delay Variation i.e. Jitter - RFC 8570 */
uint32_t pkt_loss; /* Unidirectional Link Packet Loss - RFC 8570 */
float res_bw; /* Unidirectional Residual Bandwidth - RFC 8570 */
float ava_bw; /* Unidirectional Available Bandwidth - RFC 8570 */
float use_bw; /* Unidirectional Utilized Bandwidth - RFC 8570 */
/* Segment Routing Adjacency & LAN Adjacency Segment ID */
struct isis_item_list adj_sid;
struct isis_item_list lan_sid;
};
#define IS_COMPAT_MT_TLV(tlv_type) \
@ -329,7 +544,6 @@ struct list *isis_fragment_tlvs(struct isis_tlvs *tlvs, size_t size);
#define ISIS_MT_AT_MASK 0x4000
#endif
void isis_tlvs_add_auth(struct isis_tlvs *tlvs, struct isis_passwd *passwd);
void isis_tlvs_add_area_addresses(struct isis_tlvs *tlvs,
struct list *addresses);
@ -359,6 +573,8 @@ void isis_tlvs_add_csnp_entries(struct isis_tlvs *tlvs, uint8_t *start_id,
struct isis_lsp **last_lsp);
void isis_tlvs_set_dynamic_hostname(struct isis_tlvs *tlvs,
const char *hostname);
void isis_tlvs_set_router_capability(struct isis_tlvs *tlvs,
const struct isis_router_cap *cap);
void isis_tlvs_set_te_router_id(struct isis_tlvs *tlvs,
const struct in_addr *id);
void isis_tlvs_add_oldstyle_ip_reach(struct isis_tlvs *tlvs,
@ -371,11 +587,21 @@ void isis_tlvs_add_ipv6_dstsrc_reach(struct isis_tlvs *tlvs, uint16_t mtid,
struct prefix_ipv6 *dest,
struct prefix_ipv6 *src,
uint32_t metric);
struct isis_ext_subtlvs *isis_alloc_ext_subtlvs(void);
void isis_tlvs_add_adj_sid(struct isis_ext_subtlvs *exts,
struct isis_adj_sid *adj);
void isis_tlvs_del_adj_sid(struct isis_ext_subtlvs *exts,
struct isis_adj_sid *adj);
void isis_tlvs_add_lan_adj_sid(struct isis_ext_subtlvs *exts,
struct isis_lan_adj_sid *lan);
void isis_tlvs_del_lan_adj_sid(struct isis_ext_subtlvs *exts,
struct isis_lan_adj_sid *lan);
void isis_tlvs_add_oldstyle_reach(struct isis_tlvs *tlvs, uint8_t *id,
uint8_t metric);
void isis_tlvs_add_extended_reach(struct isis_tlvs *tlvs, uint16_t mtid,
uint8_t *id, uint32_t metric,
uint8_t *subtlvs, uint8_t subtlv_len);
struct isis_ext_subtlvs *subtlvs);
const char *isis_threeway_state_name(enum isis_threeway_state state);

View File

@ -53,6 +53,8 @@
struct zclient *zclient = NULL;
DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp))
/* Router-id update message from zebra. */
static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
{
@ -82,6 +84,8 @@ static int isis_zebra_if_add(ZAPI_CALLBACK_ARGS)
isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp),
ifp);
hook_call(isis_if_new_hook, ifp);
return 0;
}

View File

@ -24,6 +24,8 @@
extern struct zclient *zclient;
DECLARE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp));
void isis_zebra_init(struct thread_master *);
void isis_zebra_stop(void);

View File

@ -47,6 +47,7 @@ extern "C" {
#define MPLS_LABEL_OAM_ALERT 14 /* [RFC3429] */
#define MPLS_LABEL_EXTENSION 15 /* [RFC7274] */
#define MPLS_LABEL_MAX 1048575
#define MPLS_LABEL_VALUE_MASK 0x000FFFFF
#define MPLS_LABEL_NONE 0xFFFFFFFF /* for internal use only */
/* Minimum and maximum label values */