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
