else
api.tag = 0;
- if (command == ZEBRA_IPV4_ROUTE_ADD)
+ if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD)
{
if (bgp_debug_zebra((struct prefix *)&p))
{
bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
api.metric, api.type, api.instance, api.tag);
}
- else
+ else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL)
{
if (bgp_debug_zebra((struct prefix *)&p))
{
if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
return 0;
- if (command == ZEBRA_IPV6_ROUTE_ADD)
+ if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
{
if (bgp_debug_zebra((struct prefix *)&p))
{
bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
api.metric, api.type, api.instance, api.tag);
}
- else
+ else if (command == ZEBRA_REDISTRIBUTE_IPV6_DEL)
{
if (bgp_debug_zebra((struct prefix *)&p))
{
zclient->interface_nbr_address_delete = bgp_interface_nbr_address_delete;
zclient->ipv4_route_add = zebra_read_ipv4;
zclient->ipv4_route_delete = zebra_read_ipv4;
+ zclient->redistribute_route_ipv4_add = zebra_read_ipv4;
+ zclient->redistribute_route_ipv4_del = zebra_read_ipv4;
zclient->interface_up = bgp_interface_up;
zclient->interface_down = bgp_interface_down;
#ifdef HAVE_IPV6
zclient->ipv6_route_add = zebra_read_ipv6;
zclient->ipv6_route_delete = zebra_read_ipv6;
+ zclient->redistribute_route_ipv6_add = zebra_read_ipv6;
+ zclient->redistribute_route_ipv6_del = zebra_read_ipv6;
#endif /* HAVE_IPV6 */
zclient->nexthop_update = bgp_read_nexthop_update;
zclient->import_check_update = bgp_read_import_check_update;
else
api.metric = 0;
- if (command == ZEBRA_IPV4_ROUTE_ADD)
+ if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD)
{
if (isis->debugs & DEBUG_ZEBRA)
zlog_debug ("IPv4 Route add from Z");
zclient->interface_address_delete = isis_zebra_if_address_del;
zclient->ipv4_route_add = isis_zebra_read_ipv4;
zclient->ipv4_route_delete = isis_zebra_read_ipv4;
+ zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4;
+ zclient->redistribute_route_ipv4_del = isis_zebra_read_ipv4;
#ifdef HAVE_IPV6
zclient->ipv6_route_add = isis_zebra_read_ipv6;
zclient->ipv6_route_delete = isis_zebra_read_ipv6;
+ zclient->redistribute_route_ipv6_add = isis_zebra_read_ipv6;
+ zclient->redistribute_route_ipv6_del = isis_zebra_read_ipv6;
#endif /* HAVE_IPV6 */
return;
if (zclient->bfd_dest_replay)
(*zclient->bfd_dest_replay) (command, zclient, length);
break;
+ case ZEBRA_REDISTRIBUTE_IPV4_ADD:
+ if (zclient->redistribute_route_ipv4_add)
+ (*zclient->redistribute_route_ipv4_add) (command, zclient, length);
+ break;
+ case ZEBRA_REDISTRIBUTE_IPV4_DEL:
+ if (zclient->redistribute_route_ipv4_del)
+ (*zclient->redistribute_route_ipv4_del) (command, zclient, length);
+ break;
+ case ZEBRA_REDISTRIBUTE_IPV6_ADD:
+ if (zclient->redistribute_route_ipv6_add)
+ (*zclient->redistribute_route_ipv6_add) (command, zclient, length);
+ break;
+ case ZEBRA_REDISTRIBUTE_IPV6_DEL:
+ if (zclient->redistribute_route_ipv6_del)
+ (*zclient->redistribute_route_ipv6_del) (command, zclient, length);
+ break;
default:
break;
}
int (*nexthop_update) (int, struct zclient *, uint16_t);
int (*import_check_update) (int, struct zclient *, uint16_t);
int (*bfd_dest_replay) (int, struct zclient *, uint16_t);
+ int (*redistribute_route_ipv4_add) (int, struct zclient *, uint16_t);
+ int (*redistribute_route_ipv4_del) (int, struct zclient *, uint16_t);
+ int (*redistribute_route_ipv6_add) (int, struct zclient *, uint16_t);
+ int (*redistribute_route_ipv6_del) (int, struct zclient *, uint16_t);
};
/* Zebra API message flag. */
#define ZEBRA_BFD_DEST_DEREGISTER 35
#define ZEBRA_BFD_DEST_UPDATE 36
#define ZEBRA_BFD_DEST_REPLAY 37
-#define ZEBRA_MESSAGE_MAX 38
+#define ZEBRA_REDISTRIBUTE_IPV4_ADD 38
+#define ZEBRA_REDISTRIBUTE_IPV4_DEL 39
+#define ZEBRA_REDISTRIBUTE_IPV6_ADD 40
+#define ZEBRA_REDISTRIBUTE_IPV6_DEL 41
+#define ZEBRA_MESSAGE_MAX 42
/* Marker value used in new Zserv, in the byte location corresponding
* the command value in the old zserv header. To allow old and new
zebra_route_string(api.type), prefixstr, nexthopstr, ifindex);
}
- if (command == ZEBRA_IPV6_ROUTE_ADD)
+ if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
ospf6_asbr_redistribute_add (api.type, ifindex, (struct prefix *) &p,
api.nexthop_num, nexthop);
else
zclient->interface_address_delete = ospf6_zebra_if_address_update_delete;
zclient->ipv4_route_add = NULL;
zclient->ipv4_route_delete = NULL;
+ zclient->redistribute_route_ipv4_add = NULL;
+ zclient->redistribute_route_ipv4_del = NULL;
zclient->ipv6_route_add = ospf6_zebra_read_ipv6;
zclient->ipv6_route_delete = ospf6_zebra_read_ipv6;
+ zclient->redistribute_route_ipv6_add = ospf6_zebra_read_ipv6;
+ zclient->redistribute_route_ipv6_del = ospf6_zebra_read_ipv6;
/* redistribute connected route by default */
/* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */
struct external_info *new;
struct route_node *rn;
struct ospf_external *ext;
+ char inetbuf[INET6_BUFSIZ];
ext = ospf_external_lookup(type, instance);
if (!ext)
if (rn)
if (rn->info)
{
- route_unlock_node (rn);
- zlog_warn ("Redistribute[%s][%d]: %s/%d already exists, discard.",
+ new = rn->info;
+ if ((new->ifindex == ifindex) &&
+ (new->nexthop.s_addr == nexthop.s_addr) && (new->tag == tag))
+ {
+ route_unlock_node(rn);
+ return NULL; /* NULL => no LSA to refresh */
+ }
+
+ inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, INET6_BUFSIZ);
+ zlog_warn ("Redistribute[%s][%d]: %s/%d discarding old info with NH %s.",
ospf_redist_string(type), instance,
- inet_ntoa (p.prefix), p.prefixlen);
- /* XFREE (MTYPE_OSPF_TMP, rn->info); */
- return rn->info;
+ inet_ntoa (p.prefix), p.prefixlen, inetbuf);
+ XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
+ rn->info = NULL;
}
/* Create new External info instance. */
new->nexthop = nexthop;
new->tag = tag;
+ /* we don't unlock rn from the get() because we're attaching the info */
if (rn)
rn->info = new;
if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
- zlog_debug ("Redistribute[%s]: %s/%d external info created.",
- ospf_redist_string(type),
- inet_ntoa (p.prefix), p.prefixlen);
+ {
+ inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, INET6_BUFSIZ);
+ zlog_debug ("Redistribute[%s]: %s/%d external info created, with NH %s",
+ ospf_redist_string(type),
+ inet_ntoa (p.prefix), p.prefixlen, inetbuf);
+ }
return new;
}
if (ospf == NULL)
return 0;
- if (command == ZEBRA_IPV4_ROUTE_ADD)
+ if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD)
{
/* XXX|HACK|TODO|FIXME:
* Maybe we should ignore reject/blackhole routes? Testing shows that
ei = ospf_external_info_add (api.type, api.instance, p, ifindex,
nexthop, api.tag);
-
+ if (ei == NULL)
+ {
+ /* Nothing has changed, so nothing to do; return */
+ return 0;
+ }
if (ospf->router_id.s_addr == 0)
/* Set flags to generate AS-external-LSA originate event
for each redistributed protocols later. */
current = ospf_external_info_find_lsa (ospf, &ei->p);
if (!current)
ospf_external_lsa_originate (ospf, ei);
- else if (IS_LSA_MAXAGE (current))
- ospf_external_lsa_refresh (ospf, current,
- ei, LSA_REFRESH_FORCE);
else
- zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
- inet_ntoa (p.prefix));
+ {
+ if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
+ zlog_debug ("ospf_zebra_read_ipv4() : %s refreshing LSA",
+ inet_ntoa (p.prefix));
+ ospf_external_lsa_refresh (ospf, current,
+ ei, LSA_REFRESH_FORCE);
+ }
}
}
}
}
- else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
+ else /* if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) */
{
ospf_external_info_delete (api.type, api.instance, p);
if (is_prefix_default (&p))
zclient->interface_address_delete = ospf_interface_address_delete;
zclient->ipv4_route_add = ospf_zebra_read_ipv4;
zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
+ zclient->redistribute_route_ipv4_add = ospf_zebra_read_ipv4;
+ zclient->redistribute_route_ipv4_del = ospf_zebra_read_ipv4;
access_list_add_hook (ospf_filter_update);
access_list_delete_hook (ospf_filter_update);
api.metric = 0;
/* Then fetch IPv4 prefixes. */
- if (command == ZEBRA_IPV4_ROUTE_ADD)
+ if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD)
rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex,
&nexthop, api.metric, api.distance);
- else
+ else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL)
rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
return 0;
zclient->ipv4_route_delete = rip_zebra_read_ipv4;
zclient->interface_up = rip_interface_up;
zclient->interface_down = rip_interface_down;
+ zclient->redistribute_route_ipv4_add = rip_zebra_read_ipv4;
+ zclient->redistribute_route_ipv4_del = rip_zebra_read_ipv4;
/* Install zebra node. */
install_node (&zebra_node, config_write_zebra);
RNODE_FOREACH_RIB (rn, newrib)
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
&& newrib->distance != DISTANCE_INFINITY)
- zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_ADD, client, &rn->p, newrib);
route_unlock_node (rn);
}
}
RNODE_FOREACH_RIB (rn, newrib)
if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)
&& newrib->distance != DISTANCE_INFINITY)
- zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_ADD, client, &rn->p, newrib);
route_unlock_node (rn);
}
}
&& zebra_check_addr (&rn->p))
{
client->redist_v4_add_cnt++;
- zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, &rn->p, newrib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_ADD, client, &rn->p, newrib);
}
#ifdef HAVE_IPV6
&& zebra_check_addr (&rn->p))
{
client->redist_v6_add_cnt++;
- zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_ADD, client, &rn->p, newrib);
}
#endif /* HAVE_IPV6 */
}
rib->instance)))
{
client->redist_v4_add_cnt++;
- zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_ADD, client,
+ p, rib);
}
#ifdef HAVE_IPV6
if ((p->family == AF_INET6) &&
rib->instance)))
{
client->redist_v6_add_cnt++;
- zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_ADD, client,
+ p, rib);
}
#endif /* HAVE_IPV6 */
}
rib->instance))
{
client->redist_v4_add_cnt++;
- zsend_route_multipath (ZEBRA_IPV4_ROUTE_ADD, client, p, rib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_ADD, client,
+ p, rib);
}
#ifdef HAVE_IPV6
if ((p->family == AF_INET6) &&
rib->instance))
{
client->redist_v6_add_cnt++;
- zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, p, rib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_ADD, client,
+ p, rib);
}
#endif /* HAVE_IPV6 */
}
(client->redist_default ||
redist_check_instance(&client->redist[AFI_IP][rib->type],
rib->instance)))
- zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_DEL, client, p,
rib);
#ifdef HAVE_IPV6
if ((p->family == AF_INET6) &&
(client->redist_default ||
redist_check_instance(&client->redist[AFI_IP6][rib->type],
rib->instance)))
- zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
- rib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_DEL, client, p,
+ rib);
#endif /* HAVE_IPV6 */
}
else
if ((p->family == AF_INET) &&
redist_check_instance(&client->redist[AFI_IP][rib->type],
rib->instance))
- zsend_route_multipath (ZEBRA_IPV4_ROUTE_DELETE, client, p,
- rib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV4_DEL, client, p,
+ rib);
#ifdef HAVE_IPV6
if ((p->family == AF_INET6) &&
redist_check_instance(&client->redist[AFI_IP6][rib->type],
rib->instance))
- zsend_route_multipath (ZEBRA_IPV6_ROUTE_DELETE, client, p,
- rib);
+ zsend_redistribute_route (ZEBRA_REDISTRIBUTE_IPV6_DEL, client, p,
+ rib);
#endif /* HAVE_IPV6 */
}
}
{
zfpm_trigger_update (rn, "updating existing route");
- redistribute_delete (&rn->p, select);
-
if (! RIB_SYSTEM_ROUTE (select))
{
/* For v4, use the replace semantics of netlink. */
if (PREFIX_FAMILY (&rn->p) == AF_INET)
- update_ok = 1;
+ update_ok = 1;
else
rib_uninstall_kernel (rn, select);
}
}
if (! RIB_SYSTEM_ROUTE (select))
rib_install_kernel (rn, select, update_ok);
+
+ /* assuming that the receiver knows how to dedup */
redistribute_add (&rn->p, select);
}
else
{
+ /* Withdraw unreachable redistribute route */
+ redistribute_delete(&rn->p, select);
+
/* For IPv4, do the uninstall here. */
if (update_ok)
rib_uninstall_kernel (rn, select);
zfpm_trigger_update (rn, "removing existing route");
- redistribute_delete (&rn->p, fib);
+ /* If there's no route to replace this with, withdraw redistribute */
+ if (!select)
+ redistribute_delete(&rn->p, fib);
if (! RIB_SYSTEM_ROUTE (fib))
{
*/
if (PREFIX_FAMILY (&rn->p) == AF_INET)
{
- if (!select || RIB_SYSTEM_ROUTE(select))
+ if (!select)
rib_uninstall_kernel (rn, fib);
else
update_ok = 1;
if (! RIB_SYSTEM_ROUTE (select))
rib_install_kernel (rn, select, update_ok);
SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
+ /* Unconditionally announce, this part is exercised by new routes */
redistribute_add (&rn->p, select);
}
else
assert (fib);
rib_uninstall_kernel (rn, fib);
}
+ /* if "select", the earlier redist delete wouldn't have happened */
+ redistribute_delete(&rn->p, select);
}
UNSET_FLAG(select->flags, ZEBRA_FLAG_CHANGED);
}
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
{
- redistribute_delete (&rn->p, rib);
/* If there are other active nexthops, do an update. */
if (rib->nexthop_active_num > 1)
{
redistribute_add (&rn->p, rib);
}
else
- rib_uninstall_kernel (rn, rib);
+ {
+ redistribute_delete (&rn->p, rib);
+ rib_uninstall_kernel (rn, rib);
+ }
}
/* Delete the nexthop and dereg from NHT */
}
/*
- * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
- * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
- * situations:
- * - when the client starts up, and requests default information
- * by sending a ZEBRA_REDISTRIBUTE_DEFAULT_ADD to the zebra server, in the
- * - case of rip, ripngd, ospfd and ospf6d, when the client sends a
- * ZEBRA_REDISTRIBUTE_ADD as a result of the "redistribute" vty cmd,
- * - when the zebra server redistributes routes after it updates its rib
+ * This is the new function to announce and withdraw redistributed routes, used
+ * by Zebra. This is the old zsend_route_multipath() function. That function
+ * was duplicating code to send a lot of information that was essentially thrown
+ * away or ignored by the receiver. This is the leaner function that is not a
+ * duplicate of the zapi_ipv4_route_add/del.
*
- * The zebra server sends clients a ZEBRA_IPV4_ROUTE_DELETE or a
- * ZEBRA_IPV6_ROUTE_DELETE via zsend_route_multipath when:
- * - a "ip route" or "ipv6 route" vty command is issued, a prefix is
- * - deleted from zebra's rib, and this info
- * has to be redistributed to the clients
- *
- * XXX The ZEBRA_IPV*_ROUTE_ADD message is also sent by the client to the
- * zebra server when the client wants to tell the zebra server to add a
- * route to the kernel (zapi_ipv4_add etc. ). Since it's essentially the
- * same message being sent back and forth, this function and
- * zapi_ipv{4,6}_{add, delete} should be re-written to avoid code
- * duplication.
+ * The primary difference is that this function merely sends a single NH instead of
+ * all the nexthops.
*/
int
-zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
- struct rib *rib)
+zsend_redistribute_route (int cmd, struct zserv *client, struct prefix *p,
+ struct rib *rib)
{
int psize;
struct stream *s;
unsigned long nhnummark = 0, messmark = 0;
int nhnum = 0;
u_char zapi_flags = 0;
-
+ struct nexthop dummy_nh;
+
s = client->obuf;
stream_reset (s);
-
+ memset(&dummy_nh, 0, sizeof(struct nexthop));
+
zserv_create_header (s, cmd);
-
+
/* Put type and nexthop. */
stream_putc (s, rib->type);
stream_putw (s, rib->instance);
stream_putc (s, rib->flags);
-
+
/* marker for message flags field */
messmark = stream_get_endp (s);
stream_putc (s, 0);
stream_putc (s, p->prefixlen);
stream_write (s, (u_char *) & p->u.prefix, psize);
- /*
- * XXX The message format sent by zebra below does not match the format
- * of the corresponding message expected by the zebra server
- * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
- * (is there a bug on the client side if more than one segment is sent?)
- * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
- * is hard-coded.
- */
- /* Nexthop */
-
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
{
+ /* We don't send any nexthops when there's a multipath */
+ if (rib->nexthop_active_num > 1)
+ {
+ SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
+ SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
+
+ stream_putc(s, 1);
+ if (p->family == AF_INET)
+ {
+ stream_put_in_addr (s, &dummy_nh.gate.ipv4);
+ }
+ else if (p->family == AF_INET6)
+ {
+ stream_write (s, (u_char *) &dummy_nh.gate.ipv6, 16);
+ }
+ else
+ {
+ /* We don't handle anything else now, abort */
+ zlog_err("%s: Unable to redistribute route of unknown family, %d\n",
+ __func__, p->family);
+ return -1;
+ }
+ stream_putc (s, 1);
+ stream_putl (s, 0); /* dummy ifindex */
+ break;
+ }
+
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
|| nexthop_has_fib_child(nexthop))
{
SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
-
if (nhnummark == 0)
{
nhnummark = stream_get_endp (s);
stream_putc (s, 1); /* placeholder */
}
-
nhnum++;
switch(nexthop->type)
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
case NEXTHOP_TYPE_IPV6_IFNAME:
- stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
+ /* Only BGP supports IPv4 prefix with IPv6 NH, so kill this */
+ if (p->family == AF_INET)
+ stream_put_in_addr(s, &dummy_nh.gate.ipv4);
+ else
+ stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
break;
#endif
default:
- if (cmd == ZEBRA_IPV4_ROUTE_ADD
- || cmd == ZEBRA_IPV4_ROUTE_DELETE)
+ if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD
+ || cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL)
{
struct in_addr empty;
memset (&empty, 0, sizeof (struct in_addr));
}
/* Metric */
- if (cmd == ZEBRA_IPV4_ROUTE_ADD || cmd == ZEBRA_IPV6_ROUTE_ADD)
+ if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD || cmd == ZEBRA_REDISTRIBUTE_IPV6_ADD)
{
SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
stream_putc (s, rib->distance);
stream_putw(s, rib->tag);
}
}
-
+
/* write real message flags value */
stream_putc_at (s, messmark, zapi_flags);
-
+
/* Write next-hop number */
if (nhnummark)
stream_putc_at (s, nhnummark, nhnum);
-
+
/* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s));
struct in6_addr *, u_char);
extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *, u_char);
extern int zsend_interface_update (int, struct zserv *, struct interface *);
-extern int zsend_route_multipath (int, struct zserv *, struct prefix *,
- struct rib *);
+extern int zsend_redistribute_route (int, struct zserv *, struct prefix *,
+ struct rib *);
extern int zsend_router_id_update(struct zserv *, struct prefix *);
extern pid_t pid;