mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 11:50:21 +00:00
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:
parent
16f1b9ee29
commit
f8c06e2c52
@ -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>
|
||||
|
@ -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 = \
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
1372
isisd/isis_te.c
Normal file
File diff suppressed because it is too large
Load Diff
331
isisd/isis_te.h
Normal file
331
isisd/isis_te.h
Normal 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 */
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user