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

Reply via email to