Add support of Traffic Engineering to IS-IS

These patches is an implementation of RFC5305 that enable the
support of Traffic Engineering in IS-IS

* isisd/Makefile.am: Add new files isis_te.c and isis_te.h
* isisd/isis_circuit.[c,h]: Add new mpls_te_circuit structure to isis_circuit
structure to handle new Traffic Engineering TLVs
* isisd/isis_lsp.c: Update LSP handler to mux/demux Traffic Engineering TLVs
* isisd/isis_main.c: Add initialisation of ISIS TE
* isisd/isis_pdu.c: Update function process_p2p_hello() to retrieve remote IP
address to populate Traffic Engineering TLV.
* isisd/isis_te.[c,]: Implementation of RFC5305
* isisd/isis_tlv.[c,h]: Update TLV definition and function to handle
Traffic Engineering ones
* isisd/isis_zebra.c: Add new function isis_zebra_link_params() to retrieve
the link parameters of interfaces from ZBus to populate the Traffic Engineering
TLVs
* isisd/isisd.[c,h]: Add Traffic Engineering support with new debug command

Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
This commit is contained in:
Olivier Dugeon 2016-04-19 19:03:05 +02:00 committed by Donald Sharp
parent 16f1b9ee29
commit f8c06e2c52
15 changed files with 1896 additions and 18 deletions

View File

@ -2,3 +2,4 @@ Sampo Saaristo <sambo@cs.tut.fi>
Ofer Wald <ofersf@islands.co.il>
Hannes Gredler <hannes@gredler.at>
Subbaiah Venkata <svenkata@google.com>
Olivier Dugeon <olivier.dugeon@orange.com>

View File

@ -16,7 +16,7 @@ libisis_a_SOURCES = \
isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.c \
isis_tlv.c isisd.c isis_misc.c isis_zebra.c isis_dr.c \
isis_flags.c isis_dynhn.c iso_checksum.c isis_csm.c isis_events.c \
isis_spf.c isis_redist.c isis_route.c isis_routemap.c \
isis_spf.c isis_redist.c isis_route.c isis_routemap.c isis_te.c \
isis_vty.c
@ -25,7 +25,7 @@ noinst_HEADERS = \
isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_redist.h \
isis_route.h isis_routemap.h \
isis_route.h isis_routemap.h isis_te.h \
include-netbsd/clnp.h include-netbsd/esis.h include-netbsd/iso.h
isisd_SOURCES = \

View File

@ -37,6 +37,7 @@
#include "linklist.h"
#include "command.h"
#include "thread.h"
#include "vty.h"
#include "hash.h"
#include "prefix.h"
#include "stream.h"
@ -58,6 +59,7 @@
#include "isisd/isisd.h"
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"
#include "isisd/isis_te.h"
/*
* Prototypes.
@ -96,6 +98,8 @@ isis_circuit_new ()
circuit->te_metric[i] = DEFAULT_CIRCUIT_METRIC;
}
circuit->mtc = mpls_te_circuit_new();
return circuit;
}
@ -222,6 +226,10 @@ isis_circuit_add_addr (struct isis_circuit *circuit,
ipv4->prefixlen = connected->address->prefixlen;
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);
if (circuit->area)
lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
@ -518,6 +526,7 @@ 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

View File

@ -112,13 +112,14 @@ struct isis_circuit
*/
struct isis_passwd passwd; /* Circuit rx/tx password */
int is_type; /* circuit is type == level of circuit
* diffrenciated from circuit type (media) */
* differentiated from circuit type (media) */
u_int32_t hello_interval[2]; /* l1HelloInterval in msecs */
u_int16_t hello_multiplier[2]; /* l1HelloMultiplier */
u_int16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */
u_int16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */
u_int8_t metric[2];
u_int32_t te_metric[2];
struct mpls_te_circuit *mtc; /* Support for MPLS-TE parameters - see isis_te.[c,h] */
int ip_router; /* Route IP ? */
int is_passive; /* Is Passive ? */
struct list *ip_addrs; /* our IP addresses */

View File

@ -52,6 +52,7 @@
#include "isisd/isis_csm.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_te.h"
#ifdef TOPOLOGY_GENERATE
#include "spgrid.h"
@ -981,6 +982,8 @@ lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost)
lspid_print (te_is_neigh->neigh_id, LSPid, dynhost, 0);
vty_out (vty, " Metric : %-8d IS-Extended : %s%s",
GET_TE_METRIC(te_is_neigh), LSPid, VTY_NEWLINE);
if (IS_MPLS_TE(isisMplsTE))
mpls_te_print_detail(vty, te_is_neigh);
}
/* TE IPv4 tlv */
@ -1091,6 +1094,64 @@ lsp_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to,
return;
}
/* Process IS_NEIGHBOURS TLV with TE subTLVs */
void
lsp_te_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to, int frag_thold)
{
int count, size = 0;
struct listnode *node, *nextnode;
struct te_is_neigh *elem;
/* Start computing real size of TLVs */
for (ALL_LIST_ELEMENTS (*from, node, nextnode, elem))
size = size + elem->sub_tlvs_length + IS_NEIGHBOURS_LEN;
/* can we fit all ? */
if (!FRAG_NEEDED (lsp->pdu, frag_thold, size))
{
tlv_add_te_is_neighs (*from, lsp->pdu);
if (listcount (*to) != 0)
{
for (ALL_LIST_ELEMENTS (*from, node, nextnode, elem))
{
listnode_add (*to, elem);
list_delete_node (*from, node);
}
}
else
{
list_free (*to);
*to = *from;
*from = NULL;
}
}
else
{
/* fit all we can */
/* Compute remaining place in LSP PDU */
count = FRAG_THOLD (lsp->pdu, frag_thold) - 2 -
(STREAM_SIZE (lsp->pdu) - STREAM_REMAIN (lsp->pdu));
/* Determine size of TE SubTLVs */
elem = (struct te_is_neigh *)listgetdata ((struct listnode *)listhead (*from));
count = count - elem->sub_tlvs_length - IS_NEIGHBOURS_LEN;
if (count > 0)
{
while (count > 0)
{
listnode_add (*to, listgetdata ((struct listnode *)listhead (*from)));
listnode_delete (*from, listgetdata ((struct listnode *)listhead (*from)));
elem = (struct te_is_neigh *)listgetdata ((struct listnode *)listhead (*from));
count = count - elem->sub_tlvs_length - IS_NEIGHBOURS_LEN;
}
tlv_add_te_is_neighs (*to, lsp->pdu);
}
}
lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu));
return;
}
static u_int16_t
lsp_rem_lifetime (struct isis_area *area, int level)
{
@ -1631,6 +1692,14 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
}
else
{
/* Check if MPLS_TE is activate */
if (IS_MPLS_TE(isisMplsTE) && HAS_LINK_PARAMS(circuit->interface))
/* Add SubTLVs & Adjust real size of SubTLVs */
te_is_neigh->sub_tlvs_length = add_te_subtlvs(te_is_neigh->sub_tlvs, circuit->mtc);
else
/* Or keep only TE metric with no SubTLVs if MPLS_TE is off */
te_is_neigh->sub_tlvs_length = 0;
listnode_add (tlv_data.te_is_neighs, te_is_neigh);
lsp_debug("ISIS (%s): Adding DIS %s.%02x as te-style neighbor",
area->area_tag, sysid_print(te_is_neigh->neigh_id),
@ -1679,6 +1748,18 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
memcpy (te_is_neigh->neigh_id, nei->sysid, ISIS_SYS_ID_LEN);
metric = circuit->te_metric[level - 1];
SET_TE_METRIC(te_is_neigh, metric);
/* Check if MPLS_TE is activate */
if (IS_MPLS_TE(isisMplsTE) && 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 */
te_is_neigh->sub_tlvs_length = add_te_subtlvs(te_is_neigh->sub_tlvs, circuit->mtc);
else
/* Or keep only TE metric with no SubTLVs if MPLS_TE is off */
te_is_neigh->sub_tlvs_length = 0;
listnode_add (tlv_data.te_is_neighs, te_is_neigh);
lsp_debug("ISIS (%s): Adding te-style is reach for %s", area->area_tag,
sysid_print(te_is_neigh->neigh_id));

View File

@ -112,6 +112,8 @@ void lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost);
int lsp_print_all (struct vty *vty, dict_t * lspdb, char detail,
char dynhost);
const char *lsp_bits2string (u_char *);
void lsp_te_tlv_fit (struct isis_lsp *lsp, struct list **from,
struct list **to, int frag_thold);
/* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags (struct isis_lsp *lsp);

View File

@ -50,6 +50,8 @@
#include "isisd/isis_route.h"
#include "isisd/isis_routemap.h"
#include "isisd/isis_zebra.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_te.h"
/* Default configuration file name */
#define ISISD_DEFAULT_CONFIG "isisd.conf"
@ -348,6 +350,7 @@ main (int argc, char **argv, char **envp)
isis_spf_cmds_init ();
isis_redist_init ();
isis_route_map_init();
isis_mpls_te_init();
/* create the global 'isis' instance */
isis_new (1);

View File

@ -53,6 +53,7 @@
#include "isisd/iso_checksum.h"
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"
#include "isisd/isis_te.h"
#define ISIS_MINIMUM_FIXED_HDR_LEN 15
#define ISIS_MIN_PDU_LEN 13 /* partial seqnum pdu with id_len=2 */
@ -630,6 +631,15 @@ process_p2p_hello (struct isis_circuit *circuit)
if (found & TLVFLAG_IPV4_ADDR)
tlvs_to_adj_ipv4_addrs (&tlvs, adj);
/* Update MPLS TE Remote IP address parameter if possible */
if (IS_MPLS_TE(isisMplsTE) && circuit->mtc && IS_CIRCUIT_TE(circuit->mtc))
if (adj->ipv4_addrs != NULL && listcount(adj->ipv4_addrs) != 0)
{
struct in_addr *ip_addr;
ip_addr = (struct in_addr *)listgetdata ((struct listnode *)listhead (adj->ipv4_addrs));
set_circuitparams_rmt_ipaddr (circuit->mtc, *ip_addr);
}
#ifdef HAVE_IPV6
if (found & TLVFLAG_IPV6_ADDR)
tlvs_to_adj_ipv6_addrs (&tlvs, adj);

1372
isisd/isis_te.c Normal file

File diff suppressed because it is too large Load Diff

331
isisd/isis_te.h Normal file
View File

@ -0,0 +1,331 @@
/*
* IS-IS Rout(e)ing protocol - isis_te.c
*
* This is an implementation of RFC5305, RFC 5307 and draft-ietf-isis-te-metric-extensions-11
*
* Copyright (C) 2014 Orange Labs
* http://www.orange.com
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef _ZEBRA_ISIS_MPLS_TE_H
#define _ZEBRA_ISIS_MPLS_TE_H
/*
* Traffic Engineering information are transport through LSP:
* - Extended IS Reachability TLV = 22
* - Traffic Engineering Router ID TLV = 134
* - Extended IP Reachability TLV = 135
* - Inter-AS Reachability Information TLV = 141
*
* and support following sub-TLV:
*
* Name Value Status
* _________________________________________________
* Administartive group (color) 3 RFC5305
* Link Local/Remote Identifiers 4 RFC5307
* IPv4 interface address 6 RFC5305
* IPv4 neighbor address 8 RFC5305
* Maximum link bandwidth 9 RFC5305
* Reservable link bandwidth 10 RFC5305
* Unreserved bandwidth 11 RFC5305
* TE Default metric 18 RFC5305
* Link Protection Type 20 RFC5307
* Interface Switching Capability 21 RFC5307
* Remote AS number 24 RFC5316
* IPv4 Remote ASBR identifier 25 RFC5316
*
*/
/* 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
#define INTER_AS 0x04
#define FLOOD_L1 0x10
#define FLOOD_L2 0x20
#define FLOOD_AS 0x40
#define EMULATED 0x80
#define IS_STD_TE(x) (x & STD_TE)
#define IS_INTER_AS(x) (x & INTER_AS)
#define IS_EMULATED(x) (x & EMULATED)
#define IS_FLOOD_L1(x) (x & FLOOD_L1)
#define IS_FLOOD_L2(x) (x & FLOOD_L2)
#define IS_FLOOD_AS(x) (x & FLOOD_AS)
#define IS_INTER_AS_EMU(x) (x & INTER_AS & EMULATED)
#define IS_INTER_AS_AS(x) (x & INTER_AS & FLOOD_AS)
/*
* Following section defines subTLV (tag, length, value) structures,
* used for Traffic Engineering.
*/
struct subtlv_header
{
u_char type; /* sub_TLV_XXX type (see above) */
u_char length; /* Value portion only, in byte */
};
#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. */
u_int32_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. */
u_int32_t local; /* Link Local Identifier */
u_int32_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. */
u_char 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. */
u_int32_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__));
/* draft-ietf-isis-te-metric-extensions-11.txt */
/* 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. */
u_int32_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. */
u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ... 16777215
with Anomalous Bit (A) as Upper most bit */
u_int32_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. */
u_int32_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. */
u_int32_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;
/* 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.status == enable)
#define IS_CIRCUIT_TE(c) (c->status == enable)
/* Following structure are internal use only. */
struct isis_mpls_te
{
/* Status of MPLS-TE: enable or disable */
status_t status;
/* L1, L1-L2, L2-Only */
u_int8_t level;
/* RFC5316 */
interas_mode_t inter_as;
struct in_addr interas_areaid;
/* Circuit list on which TE are enable */
struct list *cir_list;
/* MPLS_TE router ID */
struct in_addr router_id;
};
extern struct isis_mpls_te isisMplsTE;
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) */
u_int8_t type;
/* Total size of sub_tlvs */
u_char 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;
/* draft-ietf-isis-te-metric-extension */
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);
void mpls_te_print_detail(struct vty *, struct te_is_neigh *);
void set_circuitparams_local_ipaddr (struct mpls_te_circuit *, struct in_addr);
void set_circuitparams_rmt_ipaddr (struct mpls_te_circuit *, struct in_addr);
u_char subtlvs_len (struct mpls_te_circuit *);
u_char add_te_subtlvs(u_char *, struct mpls_te_circuit *);
u_char build_te_subtlvs(u_char *, struct isis_circuit *);
void isis_link_params_update(struct isis_circuit *, struct interface *);
void isis_mpls_te_update(struct interface *);
void isis_mpls_te_config_write_router (struct vty *);
#endif /* _ZEBRA_ISIS_MPLS_TE_H */

View File

@ -42,6 +42,7 @@
#include "isisd/isis_misc.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_te.h"
void
free_tlv (void *val)
@ -229,9 +230,23 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
while (length > value_len)
{
te_is_nei = (struct te_is_neigh *) pnt;
value_len += 11;
pnt += 11;
/* FIXME - subtlvs are handled here, for now we skip */
value_len += IS_NEIGHBOURS_LEN;
pnt += IS_NEIGHBOURS_LEN;
/* FIXME - subtlvs are handled here, for now we skip */
/* FIXME: All TE SubTLVs are not necessary present in LSP PDU. */
/* So, it must be copied in a new te_is_neigh structure */
/* rather than just initialize pointer to the original LSP PDU */
/* to avoid consider the rest of lspdu as subTLVs or buffer overflow */
if (IS_MPLS_TE(isisMplsTE))
{
struct te_is_neigh *new = XCALLOC(MTYPE_ISIS_TLV, sizeof(struct te_is_neigh));
memcpy(new->neigh_id, te_is_nei->neigh_id, ISIS_SYS_ID_LEN + 1);
memcpy(new->te_metric, te_is_nei->te_metric, 3);
new->sub_tlvs_length = te_is_nei->sub_tlvs_length;
memcpy(new->sub_tlvs, pnt, te_is_nei->sub_tlvs_length);
te_is_nei = new;
}
/* Skip SUB TLVs payload */
value_len += te_is_nei->sub_tlvs_length;
pnt += te_is_nei->sub_tlvs_length;
@ -845,8 +860,8 @@ tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream)
for (ALL_LIST_ELEMENTS_RO (te_is_neighs, node, te_is_neigh))
{
/* FIXME: This will be wrong if we are going to add TE sub TLVs. */
if (pos - value + IS_NEIGHBOURS_LEN > 255)
/* FIXME: Check if Total SubTLVs size doesn't exceed 255 */
if (pos - value + IS_NEIGHBOURS_LEN + te_is_neigh->sub_tlvs_length > 255)
{
retval = add_tlv (TE_IS_NEIGHBOURS, pos - value, value, stream);
if (retval != ISIS_OK)
@ -858,9 +873,15 @@ tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream)
pos += ISIS_SYS_ID_LEN + 1;
memcpy (pos, te_is_neigh->te_metric, 3);
pos += 3;
/* Sub TLVs length. */
*pos = 0;
/* Set the total size of Sub TLVs */
*pos = te_is_neigh->sub_tlvs_length;
pos++;
/* Copy Sub TLVs if any */
if (te_is_neigh->sub_tlvs_length > 0)
{
memcpy (pos, te_is_neigh->sub_tlvs, te_is_neigh->sub_tlvs_length);
pos += te_is_neigh->sub_tlvs_length;
}
}
return add_tlv (TE_IS_NEIGHBOURS, pos - value, value, stream);

View File

@ -39,7 +39,7 @@
* LSP Entries 9 n n y ISO10589
* Authentication 10 y y y ISO10589, RFC3567
* Checksum 12 y n y RFC3358
* TE IS Reachability 22 n y n RFC5305
* Extended IS Reachability 22 n y n RFC5305
* IS Alias 24 n y n RFC3786
* IP Int. Reachability 128 n y n RFC1195
* Protocols Supported 129 y y n RFC1195
@ -50,6 +50,7 @@
* Extended IP Reachability 135 n y n RFC5305
* Dynamic Hostname 137 n y n RFC2763
* Shared Risk Link Group 138 n y y RFC5307
* Inter-AS Reachability 141 n y n RFC5316
* Restart TLV 211 y n n RFC3847
* MT IS Reachability 222 n y n RFC5120
* MT Supported 229 y y n RFC5120
@ -59,10 +60,10 @@
* MT IPv6 IP Reachability 237 n y n RFC5120
* P2P Adjacency State 240 y n n RFC3373
* IIH Sequence Number 241 y n n draft-shen-isis-iih-sequence
* Router Capability 242 - - - draft-ietf-isis-caps
* Router Capability 242 n y n RFC4971
*
*
* IS Reachability sub-TLVs we (should) support.
* IS Reachability sub-TLVs we support (See isis_te.[c,h])
* ____________________________________________________________________________
* Name Value Status
* ____________________________________________________________________________
@ -76,6 +77,8 @@
* TE Default metric 18 RFC5305
* Link Protection Type 20 RFC5307
* Interface Switching Capability 21 RFC5307
* Remote AS number 24 RFC5316
* IPv4 Remote ASBR identifier 25 RFC5316
*
*
* IP Reachability sub-TLVs we (should) support.
@ -109,6 +112,7 @@
#define IPV6_ADDR 232
#define IPV6_REACHABILITY 236
#define WAY3_HELLO 240
#define ROUTER_INFORMATION 242
#define AUTH_INFO_HDRLEN 3
@ -121,6 +125,8 @@
#define IPV6_REACH_LEN 22
#define TE_IPV4_REACH_LEN 9
#define MAX_SUBTLV_SIZE 256
/* struct for neighbor */
struct is_neigh
{
@ -128,12 +134,18 @@ struct is_neigh
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
};
/* struct for te is neighbor */
/* struct for te metric */
struct te_is_neigh
{
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
u_char te_metric[3];
u_char sub_tlvs_length;
/* Theorical Maximum SubTLVs is 256 because the sub_tlvs_length is 8 bits */
/* Practically, 118 bytes are necessary to store all supported TE parameters */
/* FIXME: A pointer will use less memory, but need to be free */
/* which is hard to fix, especially within free_tlvs() function */
/* and malloc() / free() as a CPU cost compared to the memory usage */
u_char sub_tlvs[MAX_SUBTLV_SIZE]; /* SUB TLVs storage */
};
/* Decode and encode three-octet metric into host byte order integer */

View File

@ -49,6 +49,7 @@
#include "isisd/isis_lsp.h"
#include "isisd/isis_route.h"
#include "isisd/isis_zebra.h"
#include "isisd/isis_te.h"
struct zclient *zclient = NULL;
@ -61,6 +62,13 @@ isis_router_id_update_zebra (int command, struct zclient *zclient,
struct listnode *node;
struct prefix router_id;
/*
* If ISIS TE is enable, TE Router ID is set through specific command.
* See mpls_te_router_addr() command in isis_te.c
*/
if (IS_MPLS_TE(isisMplsTE))
return 0;
zebra_router_id_update_read (zclient->ibuf, &router_id);
if (isis->router_id == router_id.u.prefix4.s_addr)
return 0;
@ -228,6 +236,23 @@ isis_zebra_if_address_del (int command, struct zclient *client,
return 0;
}
static int
isis_zebra_link_params (int command, struct zclient *zclient,
zebra_size_t length)
{
struct interface *ifp;
ifp = zebra_interface_link_params_read (zclient->ibuf);
if (ifp == NULL)
return 0;
/* Update TE TLV */
isis_mpls_te_update(ifp);
return 0;
}
static void
isis_zebra_route_add_ipv4 (struct prefix *prefix,
struct isis_route_info *route_info)
@ -680,6 +705,7 @@ isis_zebra_init (struct thread_master *master)
zclient->interface_down = isis_zebra_if_state_down;
zclient->interface_address_add = isis_zebra_if_address_add;
zclient->interface_address_delete = isis_zebra_if_address_del;
zclient->interface_link_params = isis_zebra_link_params;
zclient->ipv4_route_add = isis_zebra_read_ipv4;
zclient->ipv4_route_delete = isis_zebra_read_ipv4;
zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4;

View File

@ -54,6 +54,7 @@
#include "isisd/isis_route.h"
#include "isisd/isis_zebra.h"
#include "isisd/isis_events.h"
#include "isisd/isis_te.h"
#ifdef TOPOLOGY_GENERATE
#include "spgrid.h"
@ -98,6 +99,7 @@ isis_new (unsigned long process_id)
* uncomment the next line for full debugs
*/
/* isis->debugs = 0xFFFF; */
isisMplsTE.status = disable; /* Only support TE metric */
}
struct isis_area *
@ -781,14 +783,16 @@ print_debug (struct vty *vty, int flags, int onoff)
}
DEFUN (show_debugging,
show_debugging_cmd,
show_debugging_isis_cmd,
"show debugging isis",
SHOW_STR
"State of each debugging option\n"
ISIS_STR)
{
vty_out (vty, "IS-IS:%s", VTY_NEWLINE);
print_debug (vty, isis->debugs, 1);
if (isis->debugs) {
vty_out (vty, "IS-IS:%s", VTY_NEWLINE);
print_debug (vty, isis->debugs, 1);
}
return CMD_SUCCESS;
}
@ -2282,6 +2286,7 @@ isis_config_write (struct vty *vty)
#endif /* TOPOLOGY_GENERATE */
}
isis_mpls_te_config_write_router(vty);
}
return write;
@ -2336,7 +2341,7 @@ isis_init ()
install_element (ENABLE_NODE, &show_database_arg_detail_cmd);
install_element (ENABLE_NODE, &show_database_detail_cmd);
install_element (ENABLE_NODE, &show_database_detail_arg_cmd);
install_element (ENABLE_NODE, &show_debugging_cmd);
install_element (ENABLE_NODE, &show_debugging_isis_cmd);
install_node (&debug_node, config_write_debug);

View File

@ -197,4 +197,8 @@ extern struct thread_master *master;
} \
while (0)
#define DEBUG_TE (1<<13)
#define IS_DEBUG_ISIS(x) (isis->debugs & x)
#endif /* ISISD_H */