It's come to my attention that I have this patch attributed wrongly, As I
understand it the original patch is:

https://github.com/Quagga-RE/quagga-RE/commit/b9c1e9ac3e261231d8f1f72e3942c9be775ff2de

It was not my intention to not credit Denis for his work, my apologies to
Denis for this mistake.

I will send a new version of this patch with the correct attributions.

thanks!

donald

On Tue, Sep 29, 2015 at 4:29 PM, Donald Sharp <[email protected]>
wrote:

> From: James Li <[email protected]>
>
> This patch provides the ability to send the gateway and ifindex
> instead of ZEBRA_MESSAGE_NEXTHOP which sends the gateway or ifindex.
>
> Signed-off-by: James Li <[email protected]>
> Signed-off-by: Dinesh Dutt <[email protected]>
> Reviewed-by: JR Rivers <[email protected]>
> ---
>  lib/zclient.c     |   34 +++++++++++++++++++++++++++++++++-
>  lib/zclient.h     |    1 +
>  lib/zebra.h       |    1 +
>  zebra/rib.h       |    2 ++
>  zebra/zebra_rib.c |   30 ++++++++++++++++++++++++++++++
>  zebra/zserv.c     |    5 +++++
>  6 files changed, 72 insertions(+), 1 deletion(-)
>
> diff --git a/lib/zclient.c b/lib/zclient.c
> index 8e443e2..1433f3c 100644
> --- a/lib/zclient.c
> +++ b/lib/zclient.c
> @@ -475,6 +475,21 @@ zclient_connect (struct thread *t)
>    * nexthop information is provided, and the message describes a prefix
>    * to blackhole or reject route.
>    *
> +  * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*()
> +  * infrastructure was built around the traditional (32-bit "gate OR
> +  * ifindex") nexthop data unit. A special encoding can be used to feed
> +  * onlink (64-bit "gate AND ifindex") nexthops into zapi_ipv4_route()
> +  * using the same zapi_ipv4 structure. This is done by setting zapi_ipv4
> +  * fields as follows:
> +  *  - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
> +  *  - .nexthop_num == .ifindex_num
> +  *  - .nexthop and .ifindex are filled with gate and ifindex parts of
> +  *    each compound nexthop, both in the same order
> +  *
> +  * zapi_ipv4_route() will produce two nexthop data units for each such
> +  * interleaved 64-bit nexthop. On the zserv side of the socket it will be
> +  * mapped to a singlle NEXTHOP_TYPE_IPV4_IFINDEX_OL RIB nexthop
> structure.
> +  *
>    * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
>    * byte value.
>    *
> @@ -509,8 +524,25 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient,
> struct prefix_ipv4 *p,
>    stream_write (s, (u_char *) & p->prefix, psize);
>
>    /* Nexthop, ifindex, distance and metric information. */
> -  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
> +  /* ZAPI_MESSAGE_ONLINK implies interleaving */
> +  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_ONLINK))
>      {
> +      /* ZAPI_MESSAGE_NEXTHOP is required for proper receiving */
> +      assert (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP));
> +      /* 64-bit data units, interleaved between nexthop[] and ifindex[] */
> +      assert (api->nexthop_num == api->ifindex_num);
> +      stream_putc (s, api->nexthop_num * 2);
> +      for (i = 0; i < api->nexthop_num; i++)
> +        {
> +          stream_putc (s, ZEBRA_NEXTHOP_IPV4_ONLINK);
> +          stream_put_in_addr (s, api->nexthop[i]);
> +          stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
> +          stream_putl (s, api->ifindex[i]);
> +        }
> +    }
> +  else if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
> +     {
> +      /* traditional 32-bit data units */
>        if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
>          {
>            stream_putc (s, 1);
> diff --git a/lib/zclient.h b/lib/zclient.h
> index 19b4f0e..9f90807 100644
> --- a/lib/zclient.h
> +++ b/lib/zclient.h
> @@ -93,6 +93,7 @@ struct zclient
>  #define ZAPI_MESSAGE_IFINDEX  0x02
>  #define ZAPI_MESSAGE_DISTANCE 0x04
>  #define ZAPI_MESSAGE_METRIC   0x08
> +#define ZAPI_MESSAGE_ONLINK   0x20
>
>  /* Zserv protocol message header */
>  struct zserv_header
> diff --git a/lib/zebra.h b/lib/zebra.h
> index 8586437..0bc5309 100644
> --- a/lib/zebra.h
> +++ b/lib/zebra.h
> @@ -476,6 +476,7 @@ extern const char *zserv_command_string (unsigned int
> command);
>  #define ZEBRA_NEXTHOP_IPV6_IFINDEX       7
>  #define ZEBRA_NEXTHOP_IPV6_IFNAME        8
>  #define ZEBRA_NEXTHOP_BLACKHOLE          9
> +#define ZEBRA_NEXTHOP_IPV4_ONLINK       10
>
>  #ifndef INADDR_LOOPBACK
>  #define        INADDR_LOOPBACK 0x7f000001      /* Internet address
> 127.0.0.1.  */
> diff --git a/zebra/rib.h b/zebra/rib.h
> index 8328f23..28e9855 100644
> --- a/zebra/rib.h
> +++ b/zebra/rib.h
> @@ -465,6 +465,8 @@ extern struct nexthop *nexthop_ifname_add (struct rib
> *, char *);
>  extern struct nexthop *nexthop_blackhole_add (struct rib *);
>  extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *,
>                                          struct in_addr *);
> +extern struct nexthop * nexthop_ipv4_ifindex_ol_add (struct rib *, const
> struct in_addr *,
> +                                                    const struct in_addr
> *, const unsigned);
>  extern struct nexthop *nexthop_ipv4_ifindex_add (struct rib *,
>                                                   struct in_addr *,
>                                                   struct in_addr *,
> diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
> index 084af38..e9f8a9c 100644
> --- a/zebra/zebra_rib.c
> +++ b/zebra/zebra_rib.c
> @@ -259,6 +259,22 @@ nexthop_ipv4_ifindex_add (struct rib *rib, struct
> in_addr *ipv4,
>    return nexthop;
>  }
>
> +struct nexthop *
> +nexthop_ipv4_ifindex_ol_add (struct rib *rib, const struct in_addr *ipv4,
> +                             const struct in_addr *src, const unsigned
> int ifindex)
> +{
> +  struct nexthop *nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct
> nexthop));
> +
> +  nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
> +  IPV4_ADDR_COPY (&nexthop->gate.ipv4, ipv4);
> +  if (src)
> +    IPV4_ADDR_COPY (&nexthop->src.ipv4, src);
> +  nexthop->ifindex = ifindex;
> +  SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
> +  nexthop_add (rib, nexthop);
> +  return nexthop;
> +}
> +
>  #ifdef HAVE_IPV6
>  struct nexthop *
>  nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
> @@ -352,6 +368,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop
> *nexthop, int set,
>    int resolved;
>    struct nexthop *newhop;
>    struct nexthop *resolved_hop;
> +  struct interface *ifp;
>
>    if (nexthop->type == NEXTHOP_TYPE_IPV4)
>      nexthop->ifindex = 0;
> @@ -363,6 +380,19 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop
> *nexthop, int set,
>        nexthop->resolved = NULL;
>      }
>
> +  /* onlink flag is an indication that we need to only check that
> +   * the link is up, we won't find the GW address in the routing
> +   * table.
> +   */
> +  if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
> +    {
> +      ifp = if_lookup_by_index (nexthop->ifindex);
> +      if (ifp && if_is_operative(ifp))
> +       return 1;
> +      else
> +       return 0;
> +    }
> +
>    /* Make lookup prefix. */
>    memset (&p, 0, sizeof (struct prefix_ipv4));
>    p.family = AF_INET;
> diff --git a/zebra/zserv.c b/zebra/zserv.c
> index 8ca5615..bb41840 100644
> --- a/zebra/zserv.c
> +++ b/zebra/zserv.c
> @@ -891,6 +891,11 @@ zread_ipv4_add (struct zserv *client, u_short length,
> vrf_id_t vrf_id)
>              case ZEBRA_NEXTHOP_BLACKHOLE:
>                nexthop_blackhole_add (rib);
>                break;
> +           case ZEBRA_NEXTHOP_IPV4_ONLINK:
> +             nexthop.s_addr = stream_get_ipv4 (s);
> +             ifindex = stream_getl (s);
> +             nexthop_ipv4_ifindex_ol_add (rib, &nexthop, NULL, ifindex);
> +             break;
>              }
>         }
>      }
> --
> 1.7.10.4
>
>
_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to