Acked-by: Donald Sharp <[email protected]> On Tue, Nov 10, 2015 at 12:43 PM, Christian Franke < [email protected]> wrote:
> From: Christian Franke <[email protected]> > > Signed-off-by: Christian Franke <[email protected]> > --- > isisd/isis_circuit.c | 82 > +++++++++++++++++++++++++++++++++++++----------- > isisd/isis_circuit.h | 2 ++ > isisd/isis_constants.h | 1 - > isisd/isis_lsp.c | 24 +++++++-------- > isisd/isis_lsp.h | 3 +- > isisd/isis_pdu.c | 36 ++++++---------------- > isisd/isisd.c | 84 > ++++++++++++++++++++++++++++++++++++++++++++++++-- > isisd/isisd.h | 3 +- > 8 files changed, 172 insertions(+), 63 deletions(-) > > diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c > index 6ecaca6..9fe11c2 100644 > --- a/isisd/isis_circuit.c > +++ b/isisd/isis_circuit.c > @@ -578,6 +578,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) > { > @@ -592,6 +615,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) > { > /* > @@ -624,9 +656,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 > */ > @@ -688,11 +717,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, > @@ -1193,6 +1219,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); > @@ -1221,16 +1248,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, > @@ -1291,6 +1327,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); > @@ -1319,16 +1356,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, > diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h > index d86fee0..d883879 100644 > --- a/isisd/isis_circuit.h > +++ b/isisd/isis_circuit.h > @@ -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 */ > diff --git a/isisd/isis_constants.h b/isisd/isis_constants.h > index bb2c4b4..8b21894 100644 > --- a/isisd/isis_constants.h > +++ b/isisd/isis_constants.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 > diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c > index cdf78cb..b2059a0 100644 > --- a/isisd/isis_lsp.c > +++ b/isisd/isis_lsp.c > @@ -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; > @@ -1590,7 +1591,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; > @@ -1963,7 +1964,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; > @@ -2353,8 +2354,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); > @@ -2476,11 +2476,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. */ > diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h > index 6e7f745..92a5dfe 100644 > --- a/isisd/isis_lsp.h > +++ b/isisd/isis_lsp.h > @@ -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, > diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c > index 26efe4d..0c3f57f 100644 > --- a/isisd/isis_pdu.c > +++ b/isisd/isis_pdu.c > @@ -1895,9 +1895,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); > @@ -2121,10 +2121,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; > @@ -2160,10 +2157,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); > > @@ -2268,10 +2262,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) > @@ -2527,10 +2518,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, > @@ -2854,10 +2842,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, > @@ -3179,10 +3164,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) > diff --git a/isisd/isisd.c b/isisd/isisd.c > index 20b8e50..7146689 100644 > --- a/isisd/isisd.c > +++ b/isisd/isisd.c > @@ -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; > @@ -1545,6 +1543,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", > @@ -2990,6 +3058,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]) > { > @@ -3223,6 +3297,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); > diff --git a/isisd/isisd.h b/isisd/isisd.h > index 838a08b..6e95e8e 100644 > --- a/isisd/isisd.h > +++ b/isisd/isisd.h > @@ -91,7 +91,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 */ > -- > 2.6.1 > > > _______________________________________________ > Quagga-dev mailing list > [email protected] > https://lists.quagga.net/mailman/listinfo/quagga-dev >
_______________________________________________ Quagga-dev mailing list [email protected] https://lists.quagga.net/mailman/listinfo/quagga-dev
