mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 04:40:21 +00:00
isisd: allow to adjust lsp-mtu
Signed-off-by: Christian Franke <chris@opensourcerouting.org> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
7ed55a412f
commit
b20ccb3aa9
@ -574,6 +574,29 @@ isis_circuit_update_all_srmflags (struct isis_circuit *circuit, int is_set)
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
isis_circuit_pdu_size(struct isis_circuit *circuit)
|
||||
{
|
||||
return ISO_MTU(circuit);
|
||||
}
|
||||
|
||||
void
|
||||
isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream)
|
||||
{
|
||||
size_t stream_size = isis_circuit_pdu_size(circuit);
|
||||
|
||||
if (!*stream)
|
||||
{
|
||||
*stream = stream_new(stream_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (STREAM_SIZE(*stream) != stream_size)
|
||||
stream_resize(*stream, stream_size);
|
||||
stream_reset(*stream);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
isis_circuit_up (struct isis_circuit *circuit)
|
||||
{
|
||||
@ -588,6 +611,15 @@ isis_circuit_up (struct isis_circuit *circuit)
|
||||
if (circuit->is_passive)
|
||||
return ISIS_OK;
|
||||
|
||||
if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit))
|
||||
{
|
||||
zlog_err("Interface MTU %zu on %s is too low to support area lsp mtu %u!",
|
||||
isis_circuit_pdu_size(circuit), circuit->interface->name,
|
||||
circuit->area->lsp_mtu);
|
||||
isis_circuit_down(circuit);
|
||||
return ISIS_ERROR;
|
||||
}
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||
{
|
||||
/*
|
||||
@ -620,9 +652,6 @@ isis_circuit_up (struct isis_circuit *circuit)
|
||||
circuit->u.bc.adjdb[0] = list_new ();
|
||||
circuit->u.bc.adjdb[1] = list_new ();
|
||||
|
||||
if (circuit->area->min_bcast_mtu == 0 ||
|
||||
ISO_MTU (circuit) < circuit->area->min_bcast_mtu)
|
||||
circuit->area->min_bcast_mtu = ISO_MTU (circuit);
|
||||
/*
|
||||
* ISO 10589 - 8.4.1 Enabling of broadcast circuits
|
||||
*/
|
||||
@ -684,11 +713,8 @@ isis_circuit_up (struct isis_circuit *circuit)
|
||||
}
|
||||
|
||||
/* initialize the circuit streams after opening connection */
|
||||
if (circuit->rcv_stream == NULL)
|
||||
circuit->rcv_stream = stream_new (ISO_MTU (circuit));
|
||||
|
||||
if (circuit->snd_stream == NULL)
|
||||
circuit->snd_stream = stream_new (ISO_MTU (circuit));
|
||||
isis_circuit_stream(circuit, &circuit->rcv_stream);
|
||||
isis_circuit_stream(circuit, &circuit->snd_stream);
|
||||
|
||||
#ifdef GNU_LINUX
|
||||
THREAD_READ_ON (master, circuit->t_read, isis_receive, circuit,
|
||||
@ -1192,6 +1218,7 @@ DEFUN (ip_router_isis,
|
||||
struct isis_circuit *circuit;
|
||||
struct interface *ifp;
|
||||
struct isis_area *area;
|
||||
int rv;
|
||||
|
||||
ifp = (struct interface *) vty->index;
|
||||
assert (ifp);
|
||||
@ -1220,16 +1247,25 @@ DEFUN (ip_router_isis,
|
||||
area = vty->index;
|
||||
|
||||
circuit = isis_csm_state_change (ISIS_ENABLE, circuit, area);
|
||||
isis_circuit_if_bind (circuit, ifp);
|
||||
if (circuit->state != C_STATE_CONF && circuit->state != C_STATE_UP)
|
||||
{
|
||||
vty_out(vty, "Couldn't bring up interface, please check log.%s", VTY_NEWLINE);
|
||||
rv = CMD_WARNING;
|
||||
}
|
||||
else
|
||||
{
|
||||
isis_circuit_if_bind (circuit, ifp);
|
||||
|
||||
circuit->ip_router = 1;
|
||||
area->ip_circuits++;
|
||||
circuit_update_nlpids (circuit);
|
||||
circuit->ip_router = 1;
|
||||
area->ip_circuits++;
|
||||
circuit_update_nlpids (circuit);
|
||||
rv = CMD_SUCCESS;
|
||||
}
|
||||
|
||||
vty->node = INTERFACE_NODE;
|
||||
vty->index = ifp;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
return rv;
|
||||
}
|
||||
|
||||
DEFUN (no_ip_router_isis,
|
||||
@ -1290,6 +1326,7 @@ DEFUN (ipv6_router_isis,
|
||||
struct isis_circuit *circuit;
|
||||
struct interface *ifp;
|
||||
struct isis_area *area;
|
||||
int rv;
|
||||
|
||||
ifp = (struct interface *) vty->index;
|
||||
assert (ifp);
|
||||
@ -1318,16 +1355,25 @@ DEFUN (ipv6_router_isis,
|
||||
area = vty->index;
|
||||
|
||||
circuit = isis_csm_state_change (ISIS_ENABLE, circuit, area);
|
||||
isis_circuit_if_bind (circuit, ifp);
|
||||
if (circuit->state != C_STATE_CONF && circuit->state != C_STATE_UP)
|
||||
{
|
||||
vty_out(vty, "Couldn't bring up interface, please check log.%s", VTY_NEWLINE);
|
||||
rv = CMD_WARNING;
|
||||
}
|
||||
else
|
||||
{
|
||||
isis_circuit_if_bind (circuit, ifp);
|
||||
|
||||
circuit->ipv6_router = 1;
|
||||
area->ipv6_circuits++;
|
||||
circuit_update_nlpids (circuit);
|
||||
circuit->ipv6_router = 1;
|
||||
area->ipv6_circuits++;
|
||||
circuit_update_nlpids (circuit);
|
||||
rv = CMD_SUCCESS;
|
||||
}
|
||||
|
||||
vty->node = INTERFACE_NODE;
|
||||
vty->index = ifp;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
return rv;
|
||||
}
|
||||
|
||||
DEFUN (no_ipv6_router_isis,
|
||||
|
@ -164,5 +164,7 @@ void isis_circuit_down (struct isis_circuit *);
|
||||
void circuit_update_nlpids (struct isis_circuit *circuit);
|
||||
void isis_circuit_print_vty (struct isis_circuit *circuit, struct vty *vty,
|
||||
char detail);
|
||||
size_t isis_circuit_pdu_size(struct isis_circuit *circuit);
|
||||
void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream);
|
||||
|
||||
#endif /* _ZEBRA_ISIS_CIRCUIT_H */
|
||||
|
@ -34,7 +34,6 @@
|
||||
#define ISO_SAP 0xFE
|
||||
#define INTRADOMAIN_ROUTEING_SELECTOR 0
|
||||
#define SEQUENCE_MODULUS 4294967296
|
||||
#define RECEIVE_LSP_BUFFER_SIZE 1492
|
||||
|
||||
/*
|
||||
* implementation specific jitter values
|
||||
|
@ -575,15 +575,16 @@ lsp_new_from_stream_ptr (struct stream *stream,
|
||||
}
|
||||
|
||||
struct isis_lsp *
|
||||
lsp_new (u_char * lsp_id, u_int16_t rem_lifetime, u_int32_t seq_num,
|
||||
u_int8_t lsp_bits, u_int16_t checksum, int level)
|
||||
lsp_new(struct isis_area *area, u_char * lsp_id,
|
||||
u_int16_t rem_lifetime, u_int32_t seq_num,
|
||||
u_int8_t lsp_bits, u_int16_t checksum, int level)
|
||||
{
|
||||
struct isis_lsp *lsp;
|
||||
|
||||
lsp = XCALLOC (MTYPE_ISIS_LSP, sizeof (struct isis_lsp));
|
||||
lsp->area = area;
|
||||
|
||||
/* FIXME: Should be minimal mtu? */
|
||||
lsp->pdu = stream_new (1500);
|
||||
lsp->pdu = stream_new(LLC_LEN + area->lsp_mtu);
|
||||
if (LSP_FRAGMENT (lsp_id) == 0)
|
||||
lsp->lspu.frags = list_new ();
|
||||
lsp->isis_header = (struct isis_fixed_hdr *) (STREAM_DATA (lsp->pdu));
|
||||
@ -1131,7 +1132,7 @@ lsp_next_frag (u_char frag_num, struct isis_lsp *lsp0, struct isis_area *area,
|
||||
lsp_clear_data (lsp);
|
||||
return lsp;
|
||||
}
|
||||
lsp = lsp_new (frag_id, ntohs(lsp0->lsp_header->rem_lifetime), 0,
|
||||
lsp = lsp_new (area, frag_id, ntohs(lsp0->lsp_header->rem_lifetime), 0,
|
||||
lsp_bits_generate (level, area->overload_bit,
|
||||
area->attached_bit), 0, level);
|
||||
lsp->area = area;
|
||||
@ -1593,7 +1594,7 @@ lsp_generate (struct isis_area *area, int level)
|
||||
area->lspdb[level - 1]);
|
||||
}
|
||||
rem_lifetime = lsp_rem_lifetime (area, level);
|
||||
newlsp = lsp_new (lspid, rem_lifetime, seq_num,
|
||||
newlsp = lsp_new (area, lspid, rem_lifetime, seq_num,
|
||||
area->is_type | area->overload_bit | area->attached_bit,
|
||||
0, level);
|
||||
newlsp->area = area;
|
||||
@ -1966,7 +1967,7 @@ lsp_generate_pseudo (struct isis_circuit *circuit, int level)
|
||||
|
||||
rem_lifetime = lsp_rem_lifetime (circuit->area, level);
|
||||
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
|
||||
lsp = lsp_new (lsp_id, rem_lifetime, 1,
|
||||
lsp = lsp_new (circuit->area, lsp_id, rem_lifetime, 1,
|
||||
circuit->area->is_type | circuit->area->attached_bit,
|
||||
0, level);
|
||||
lsp->area = circuit->area;
|
||||
@ -2356,8 +2357,7 @@ lsp_purge_non_exist (struct isis_link_state_hdr *lsp_hdr,
|
||||
lsp->area = area;
|
||||
lsp->level = ((lsp_hdr->lsp_bits & LSPBIT_IST) == IS_LEVEL_1) ?
|
||||
IS_LEVEL_1 : IS_LEVEL_2;
|
||||
/* FIXME: Should be minimal mtu? */
|
||||
lsp->pdu = stream_new (1500);
|
||||
lsp->pdu = stream_new(LLC_LEN + area->lsp_mtu);
|
||||
lsp->isis_header = (struct isis_fixed_hdr *) STREAM_DATA (lsp->pdu);
|
||||
fill_fixed_hdr (lsp->isis_header, (lsp->level == IS_LEVEL_1) ? L1_LINK_STATE
|
||||
: L2_LINK_STATE);
|
||||
@ -2479,11 +2479,11 @@ generate_topology_lsps (struct isis_area *area)
|
||||
lspid[ISIS_SYS_ID_LEN - 2] = ((i >> 8) & 0xFF);
|
||||
|
||||
rem_lifetime = lsp_rem_lifetime (area, IS_LEVEL_1);
|
||||
lsp = lsp_new (lspid, rem_lifetime, 1, IS_LEVEL_1 | area->overload_bit
|
||||
| area->attached_bit, 0, 1);
|
||||
lsp = lsp_new (area, lspid, rem_lifetime, 1,
|
||||
IS_LEVEL_1 | area->overload_bit | area->attached_bit,
|
||||
0, 1);
|
||||
if (!lsp)
|
||||
return;
|
||||
lsp->area = area;
|
||||
lsp->from_topology = 1;
|
||||
|
||||
/* Creating LSP data based on topology info. */
|
||||
|
@ -66,7 +66,8 @@ int lsp_regenerate_schedule (struct isis_area *area, int level,
|
||||
int lsp_generate_pseudo (struct isis_circuit *circuit, int level);
|
||||
int lsp_regenerate_schedule_pseudo (struct isis_circuit *circuit, int level);
|
||||
|
||||
struct isis_lsp *lsp_new (u_char * lsp_id, u_int16_t rem_lifetime,
|
||||
struct isis_lsp *lsp_new (struct isis_area *area, u_char * lsp_id,
|
||||
u_int16_t rem_lifetime,
|
||||
u_int32_t seq_num, u_int8_t lsp_bits,
|
||||
u_int16_t checksum, int level);
|
||||
struct isis_lsp *lsp_new_from_stream_ptr (struct stream *stream,
|
||||
|
@ -1867,9 +1867,9 @@ process_snp (int snp_type, int level, struct isis_circuit *circuit,
|
||||
if (entry->rem_lifetime && entry->checksum && entry->seq_num &&
|
||||
memcmp (entry->lsp_id, isis->sysid, ISIS_SYS_ID_LEN))
|
||||
{
|
||||
lsp = lsp_new (entry->lsp_id, ntohs (entry->rem_lifetime),
|
||||
0, 0, entry->checksum, level);
|
||||
lsp->area = circuit->area;
|
||||
lsp = lsp_new(circuit->area, entry->lsp_id,
|
||||
ntohs(entry->rem_lifetime),
|
||||
0, 0, entry->checksum, level);
|
||||
lsp_insert (lsp, circuit->area->lspdb[level - 1]);
|
||||
ISIS_FLAGS_CLEAR_ALL (lsp->SRMflags);
|
||||
ISIS_SET_FLAG (lsp->SSNflags, circuit);
|
||||
@ -2093,10 +2093,7 @@ isis_receive (struct thread *thread)
|
||||
circuit = THREAD_ARG (thread);
|
||||
assert (circuit);
|
||||
|
||||
if (circuit->rcv_stream == NULL)
|
||||
circuit->rcv_stream = stream_new (ISO_MTU (circuit));
|
||||
else
|
||||
stream_reset (circuit->rcv_stream);
|
||||
isis_circuit_stream(circuit, &circuit->rcv_stream);
|
||||
|
||||
retval = circuit->rx (circuit, ssnpa);
|
||||
circuit->t_read = NULL;
|
||||
@ -2132,10 +2129,7 @@ isis_receive (struct thread *thread)
|
||||
|
||||
circuit->t_read = NULL;
|
||||
|
||||
if (circuit->rcv_stream == NULL)
|
||||
circuit->rcv_stream = stream_new (ISO_MTU (circuit));
|
||||
else
|
||||
stream_reset (circuit->rcv_stream);
|
||||
isis_circuit_stream(circuit, &circuit->rcv_stream);
|
||||
|
||||
retval = circuit->rx (circuit, ssnpa);
|
||||
|
||||
@ -2240,10 +2234,7 @@ send_hello (struct isis_circuit *circuit, int level)
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
if (!circuit->snd_stream)
|
||||
circuit->snd_stream = stream_new (ISO_MTU (circuit));
|
||||
else
|
||||
stream_reset (circuit->snd_stream);
|
||||
isis_circuit_stream(circuit, &circuit->snd_stream);
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||
if (level == IS_LEVEL_1)
|
||||
@ -2501,10 +2492,7 @@ build_csnp (int level, u_char * start, u_char * stop, struct list *lsps,
|
||||
unsigned long auth_tlv_offset = 0;
|
||||
int retval = ISIS_OK;
|
||||
|
||||
if (circuit->snd_stream == NULL)
|
||||
circuit->snd_stream = stream_new (ISO_MTU (circuit));
|
||||
else
|
||||
stream_reset (circuit->snd_stream);
|
||||
isis_circuit_stream(circuit, &circuit->snd_stream);
|
||||
|
||||
if (level == IS_LEVEL_1)
|
||||
fill_fixed_hdr_andstream (&fixed_hdr, L1_COMPLETE_SEQ_NUM,
|
||||
@ -2828,10 +2816,7 @@ build_psnp (int level, struct isis_circuit *circuit, struct list *lsps)
|
||||
unsigned long auth_tlv_offset = 0;
|
||||
int retval = ISIS_OK;
|
||||
|
||||
if (circuit->snd_stream == NULL)
|
||||
circuit->snd_stream = stream_new (ISO_MTU (circuit));
|
||||
else
|
||||
stream_reset (circuit->snd_stream);
|
||||
isis_circuit_stream(circuit, &circuit->snd_stream);
|
||||
|
||||
if (level == IS_LEVEL_1)
|
||||
fill_fixed_hdr_andstream (&fixed_hdr, L1_PARTIAL_SEQ_NUM,
|
||||
@ -3153,10 +3138,7 @@ ack_lsp (struct isis_link_state_hdr *hdr, struct isis_circuit *circuit,
|
||||
u_int16_t length;
|
||||
struct isis_fixed_hdr fixed_hdr;
|
||||
|
||||
if (!circuit->snd_stream)
|
||||
circuit->snd_stream = stream_new (ISO_MTU (circuit));
|
||||
else
|
||||
stream_reset (circuit->snd_stream);
|
||||
isis_circuit_stream(circuit, &circuit->snd_stream);
|
||||
|
||||
// fill_llc_hdr (stream);
|
||||
if (level == IS_LEVEL_1)
|
||||
|
@ -158,13 +158,11 @@ isis_area_create (const char *area_tag)
|
||||
area->oldmetric = 0;
|
||||
area->newmetric = 1;
|
||||
area->lsp_frag_threshold = 90;
|
||||
area->lsp_mtu = DEFAULT_LSP_MTU;
|
||||
#ifdef TOPOLOGY_GENERATE
|
||||
memcpy (area->topology_baseis, DEFAULT_TOPOLOGY_BASEIS, ISIS_SYS_ID_LEN);
|
||||
#endif /* TOPOLOGY_GENERATE */
|
||||
|
||||
/* FIXME: Think of a better way... */
|
||||
area->min_bcast_mtu = 1497;
|
||||
|
||||
area->area_tag = strdup (area_tag);
|
||||
listnode_add (isis->area_list, area);
|
||||
area->isis = isis;
|
||||
@ -1546,6 +1544,76 @@ DEFUN (no_net,
|
||||
return area_clear_net_title (vty, argv[0]);
|
||||
}
|
||||
|
||||
static
|
||||
int area_set_lsp_mtu(struct vty *vty, struct isis_area *area, unsigned int lsp_mtu)
|
||||
{
|
||||
struct isis_circuit *circuit;
|
||||
struct listnode *node;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
|
||||
{
|
||||
if(lsp_mtu > isis_circuit_pdu_size(circuit))
|
||||
{
|
||||
vty_out(vty, "ISIS area contains circuit %s, which has a maximum PDU size of %zu.%s",
|
||||
circuit->interface->name, isis_circuit_pdu_size(circuit),
|
||||
VTY_NEWLINE);
|
||||
return CMD_ERR_AMBIGUOUS;
|
||||
}
|
||||
}
|
||||
|
||||
area->lsp_mtu = lsp_mtu;
|
||||
lsp_regenerate_schedule(area, IS_LEVEL_1_AND_2, 1);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (area_lsp_mtu,
|
||||
area_lsp_mtu_cmd,
|
||||
"lsp-mtu <128-4352>",
|
||||
"Configure the maximum size of generated LSPs\n"
|
||||
"Maximum size of generated LSPs\n")
|
||||
{
|
||||
struct isis_area *area;
|
||||
|
||||
area = vty->index;
|
||||
if (!area)
|
||||
{
|
||||
vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
|
||||
return CMD_ERR_NO_MATCH;
|
||||
}
|
||||
|
||||
unsigned int lsp_mtu;
|
||||
|
||||
VTY_GET_INTEGER_RANGE("lsp-mtu", lsp_mtu, argv[0], 128, 4352);
|
||||
|
||||
return area_set_lsp_mtu(vty, area, lsp_mtu);
|
||||
}
|
||||
|
||||
DEFUN(no_area_lsp_mtu,
|
||||
no_area_lsp_mtu_cmd,
|
||||
"no lsp-mtu",
|
||||
NO_STR
|
||||
"Configure the maximum size of generated LSPs\n")
|
||||
{
|
||||
struct isis_area *area;
|
||||
|
||||
area = vty->index;
|
||||
if (!area)
|
||||
{
|
||||
vty_out (vty, "Can't find ISIS instance %s", VTY_NEWLINE);
|
||||
return CMD_ERR_NO_MATCH;
|
||||
}
|
||||
|
||||
return area_set_lsp_mtu(vty, area, DEFAULT_LSP_MTU);
|
||||
}
|
||||
|
||||
ALIAS(no_area_lsp_mtu,
|
||||
no_area_lsp_mtu_arg_cmd,
|
||||
"no lsp-mtu <128-4352>",
|
||||
NO_STR
|
||||
"Configure the maximum size of generated LSPs\n"
|
||||
"Maximum size of generated LSPs\n");
|
||||
|
||||
DEFUN (area_passwd_md5,
|
||||
area_passwd_md5_cmd,
|
||||
"area-password md5 WORD",
|
||||
@ -2991,6 +3059,12 @@ isis_config_write (struct vty *vty)
|
||||
write++;
|
||||
}
|
||||
}
|
||||
if (area->lsp_mtu != DEFAULT_LSP_MTU)
|
||||
{
|
||||
vty_out(vty, " lsp-mtu %u%s", area->lsp_mtu, VTY_NEWLINE);
|
||||
write++;
|
||||
}
|
||||
|
||||
/* Minimum SPF interval. */
|
||||
if (area->min_spf_interval[0] == area->min_spf_interval[1])
|
||||
{
|
||||
@ -3224,6 +3298,10 @@ isis_init ()
|
||||
install_element (ISIS_NODE, &is_type_cmd);
|
||||
install_element (ISIS_NODE, &no_is_type_cmd);
|
||||
|
||||
install_element (ISIS_NODE, &area_lsp_mtu_cmd);
|
||||
install_element (ISIS_NODE, &no_area_lsp_mtu_cmd);
|
||||
install_element (ISIS_NODE, &no_area_lsp_mtu_arg_cmd);
|
||||
|
||||
install_element (ISIS_NODE, &area_passwd_md5_cmd);
|
||||
install_element (ISIS_NODE, &area_passwd_md5_snpauth_cmd);
|
||||
install_element (ISIS_NODE, &area_passwd_clear_cmd);
|
||||
|
@ -93,7 +93,8 @@ struct isis_area
|
||||
struct isis_spftree *spftree6[ISIS_LEVELS]; /* The v6 SPTs */
|
||||
struct route_table *route_table6[ISIS_LEVELS]; /* IPv6 routes */
|
||||
#endif
|
||||
unsigned int min_bcast_mtu;
|
||||
#define DEFAULT_LSP_MTU 1497
|
||||
unsigned int lsp_mtu; /* Size of LSPs to generate */
|
||||
struct list *circuit_list; /* IS-IS circuits */
|
||||
struct flags flags;
|
||||
struct thread *t_tick; /* LSP walker */
|
||||
|
Loading…
Reference in New Issue
Block a user