From c8a1cb5c9db0490cd6d426999f3d1cb2df143e45 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 19 May 2015 17:58:13 -0700 Subject: [PATCH] onlink commit from Quagga-RE branch --- lib/zclient.c | 34 +++++++++++++++++++++++++++++++++- lib/zclient.h | 3 ++- lib/zebra.h | 1 + zebra/rib.h | 2 ++ zebra/zebra_rib.c | 30 ++++++++++++++++++++++++++++++ zebra/zserv.c | 5 +++++ 6 files changed, 73 insertions(+), 2 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index ac418addf3..d8ef0e8536 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -450,6 +450,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. * @@ -486,8 +501,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 9b359893ec..e1bb2000ca 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -93,7 +93,8 @@ struct zclient #define ZAPI_MESSAGE_IFINDEX 0x02 #define ZAPI_MESSAGE_DISTANCE 0x04 #define ZAPI_MESSAGE_METRIC 0x08 -#define ZAPI_MESSAGE_TAG 0x20 +#define ZAPI_MESSAGE_TAG 0x10 +#define ZAPI_MESSAGE_ONLINK 0x20 /* Zserv protocol message header */ struct zserv_header diff --git a/lib/zebra.h b/lib/zebra.h index 794a457ea8..4e976eb107 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -493,6 +493,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 65d1667b54..472bcf1d60 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -340,6 +340,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 cd9f7005cc..08f65be104 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -361,6 +361,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) @@ -455,6 +471,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, struct nexthop *newhop, *tnewhop; struct nexthop *resolved_hop; int recursing = 0; + struct interface *ifp; if (nexthop->type == NEXTHOP_TYPE_IPV4) nexthop->ifindex = 0; @@ -472,6 +489,19 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) return 0; + /* 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 56e5b19f12..3c850e4259 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1077,6 +1077,11 @@ zread_ipv4_add (struct zserv *client, u_short length) 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; } } } -- 2.39.5