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))
#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
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)
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;
+}
#endif /* HAVE_IPV6 */
+extern int connected_is_unnumbered (struct interface *);
+
#endif /*_ZEBRA_CONNECTED_H */
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 *,
#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;
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;
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)
{
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;
}
struct stream *s;
unsigned int ifindex;
u_char ifname_len;
- safi_t safi;
+ safi_t safi;
int ret;
/* Get input stream. */
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;
}
}
}