summaryrefslogtreecommitdiffstats
path: root/lib/zclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c105
1 files changed, 104 insertions, 1 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index 9d50ebc0..78e5aa31 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -516,6 +516,8 @@ zclient_connect (struct thread *t)
* If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
* byte value.
*
+ * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 2 byte value
+ *
* XXX: No attention paid to alignment.
*/
int
@@ -574,6 +576,8 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
stream_putl (s, api->metric);
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
stream_putl (s, api->mtu);
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
+ stream_putw (s, api->tag);
/* Put length at the first point of the stream. */
stream_putw_at (s, 0, stream_get_endp (s));
@@ -610,7 +614,15 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
/* Nexthop, ifindex, distance and metric information. */
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
{
- stream_putc (s, api->nexthop_num + api->ifindex_num);
+ if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
+ {
+ stream_putc (s, 1);
+ stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
+ /* XXX assert(api->nexthop_num == 0); */
+ /* XXX assert(api->ifindex_num == 0); */
+ }
+ else
+ stream_putc (s, api->nexthop_num + api->ifindex_num);
for (i = 0; i < api->nexthop_num; i++)
{
@@ -630,6 +642,8 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
stream_putl (s, api->metric);
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
stream_putl (s, api->mtu);
+ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
+ stream_putw (s, api->tag);
/* Put length at the first point of the stream. */
stream_putw_at (s, 0, stream_get_endp (s));
@@ -902,6 +916,81 @@ zebra_interface_address_read (int type, struct stream *s, vrf_id_t vrf_id)
return ifc;
}
+/*
+ * format of message for neighbor connected address is:
+ * 0
+ * 0 1 2 3 4 5 6 7
+ * +-+-+-+-+-+-+-+-+
+ * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
+ * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
+ * | |
+ * + +
+ * | ifindex |
+ * + +
+ * | |
+ * + +
+ * | |
+ * +-+-+-+-+-+-+-+-+
+ * | addr_family |
+ * +-+-+-+-+-+-+-+-+
+ * | addr... |
+ * : :
+ * | |
+ * +-+-+-+-+-+-+-+-+
+ * | addr_len | len of addr.
+ * +-+-+-+-+-+-+-+-+
+ */
+struct nbr_connected *
+zebra_interface_nbr_address_read (int type, struct stream *s)
+{
+ unsigned int ifindex;
+ struct interface *ifp;
+ struct prefix p;
+ struct nbr_connected *ifc;
+
+ /* Get interface index. */
+ ifindex = stream_getl (s);
+
+ /* Lookup index. */
+ ifp = if_lookup_by_index (ifindex);
+ if (ifp == NULL)
+ {
+ zlog_warn ("zebra_nbr_interface_address_read(%s): "
+ "Can't find interface by ifindex: %d ",
+ (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD? "ADD" : "DELETE"),
+ ifindex);
+ return NULL;
+ }
+
+ p.family = stream_getc (s);
+ stream_get (&p.u.prefix, s, prefix_blen (&p));
+ p.prefixlen = stream_getc (s);
+
+ if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD)
+ {
+ /* Currently only supporting P2P links, so any new RA source address is
+ considered as the replacement of the previously learnt Link-Local address. */
+ if (!(ifc = listnode_head(ifp->nbr_connected)))
+ {
+ ifc = nbr_connected_new ();
+ ifc->address = prefix_new ();
+ ifc->ifp = ifp;
+ listnode_add (ifp->nbr_connected, ifc);
+ }
+
+ prefix_copy(ifc->address, &p);
+ }
+ else
+ {
+ assert (type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
+
+ ifc = nbr_connected_check(ifp, &p);
+ if (ifc)
+ listnode_delete (ifp->nbr_connected, ifc);
+ }
+
+ return ifc;
+}
/* Zebra client message read function. */
static int
@@ -1021,6 +1110,14 @@ zclient_read (struct thread *thread)
if (zclient->interface_address_delete)
(*zclient->interface_address_delete) (command, zclient, length, vrf_id);
break;
+ case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
+ if (zclient->interface_nbr_address_add)
+ (*zclient->interface_nbr_address_add) (command, zclient, length, vrf_id);
+ break;
+ case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
+ if (zclient->interface_nbr_address_delete)
+ (*zclient->interface_nbr_address_delete) (command, zclient, length, vrf_id);
+ break;
case ZEBRA_INTERFACE_UP:
if (zclient->interface_up)
(*zclient->interface_up) (command, zclient, length, vrf_id);
@@ -1045,6 +1142,12 @@ zclient_read (struct thread *thread)
if (zclient->ipv6_route_delete)
(*zclient->ipv6_route_delete) (command, zclient, length, vrf_id);
break;
+ case ZEBRA_NEXTHOP_UPDATE:
+ if (zclient_debug)
+ zlog_debug("zclient rcvd nexthop update\n");
+ if (zclient->nexthop_update)
+ (*zclient->nexthop_update) (command, zclient, length, vrf_id);
+ break;
default:
break;
}