Zebra: Remove reliance on NEXTHOP_TYPE_IPV4_ONLINK

Zebra already knows if an interface is unnumbered or not.  This
is communicated to OSPF.
OSPF would only send a NEXTHOP_TYPE_IPV4_ONLINK *if* the path
was unnumbered, which it learns from Zebra.

As such, Have OSPF use the normal NEXTHOP_TYPE_IPV4_IFINDEX
type for unnumbered paths.  In Zebra, if the ifindex recieved
is unnumbered then assume that the link is NEXTHOP_FLAG_ONLINK.

Ticket: CM-8145
Reviewed-by: CCR-3771
Testing: See bug

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2015-11-16 12:48:07 -08:00
parent 25c38b240e
commit d44ca835fc
8 changed files with 57 additions and 79 deletions

View File

@ -611,23 +611,7 @@ 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. */
/* 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))
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
{
/* traditional 32-bit data units */
if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))

View File

@ -115,7 +115,6 @@ struct zclient
#define ZAPI_MESSAGE_DISTANCE 0x04
#define ZAPI_MESSAGE_METRIC 0x08
#define ZAPI_MESSAGE_TAG 0x10
#define ZAPI_MESSAGE_ONLINK 0x20
/* Zserv protocol message header */
struct zserv_header

View File

@ -387,38 +387,27 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
{
#ifdef HAVE_NETLINK
if (path->unnumbered)
{
stream_putc (s, ZEBRA_NEXTHOP_IPV4_ONLINK);
stream_put_in_addr (s, &path->nexthop);
if (path->ifindex)
stream_putl (s, path->ifindex);
else
stream_putl (s, 0);
}
else
{
if (path->nexthop.s_addr != INADDR_ANY &&
path->ifindex != 0)
{
stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX);
stream_put_in_addr (s, &path->nexthop);
stream_putl (s, path->ifindex);
}
else if (path->nexthop.s_addr != INADDR_ANY)
{
stream_putc (s, ZEBRA_NEXTHOP_IPV4);
stream_put_in_addr (s, &path->nexthop);
}
else
{
stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
if (path->ifindex)
stream_putl (s, path->ifindex);
else
stream_putl (s, 0);
}
}
if (path->unnumbered ||
(path->nexthop.s_addr != INADDR_ANY &&
path->ifindex != 0))
{
stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX);
stream_put_in_addr (s, &path->nexthop);
stream_putl (s, path->ifindex);
}
else if (path->nexthop.s_addr != INADDR_ANY)
{
stream_putc (s, ZEBRA_NEXTHOP_IPV4);
stream_put_in_addr (s, &path->nexthop);
}
else
{
stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
if (path->ifindex)
stream_putl (s, path->ifindex);
else
stream_putl (s, 0);
}
#else /* HAVE_NETLINK */
if (path->nexthop.s_addr != INADDR_ANY &&
path->ifindex != 0)

View File

@ -544,3 +544,18 @@ connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
rib_update_static(ifp->vrf_id);
}
#endif /* HAVE_IPV6 */
int
connected_is_unnumbered (struct interface *ifp)
{
struct connected *connected;
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
{
if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
connected->address->family == AF_INET)
return CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED);
}
return 0;
}

View File

@ -55,4 +55,6 @@ extern void connected_down_ipv6 (struct interface *ifp, struct connected *);
#endif /* HAVE_IPV6 */
extern int connected_is_unnumbered (struct interface *);
#endif /*_ZEBRA_CONNECTED_H */

View File

@ -385,8 +385,6 @@ 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 *,

View File

@ -45,6 +45,7 @@
#include "zebra/zebra_fpm.h"
#include "zebra/zebra_rnh.h"
#include "zebra/interface.h"
#include "zebra/connected.h"
/* Default rtm_table for all clients */
extern struct zebra_t zebrad;
@ -317,6 +318,7 @@ nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
struct in_addr *src, unsigned int ifindex)
{
struct nexthop *nexthop;
struct interface *ifp;
nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
@ -324,28 +326,16 @@ nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
if (src)
nexthop->src.ipv4 = *src;
nexthop->ifindex = ifindex;
ifp = if_lookup_by_index (nexthop->ifindex);
if (connected_is_unnumbered(ifp)) {
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
}
nexthop_add (rib, nexthop);
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;
}
struct nexthop *
nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
{
@ -456,15 +446,21 @@ 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.
/*
* Check to see if we should trust the passed in information
* for UNNUMBERED interfaces as that 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;
if (ifp && connected_is_unnumbered(ifp))
{
if (if_is_operative(ifp))
return 1;
else
return 0;
}
else
return 0;
}

View File

@ -1069,7 +1069,7 @@ zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
struct stream *s;
unsigned int ifindex;
u_char ifname_len;
safi_t safi;
safi_t safi;
int ret;
/* Get input stream. */
@ -1130,11 +1130,6 @@ 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;
}
}
}