diff options
Diffstat (limited to 'lib/zclient.c')
-rw-r--r-- | lib/zclient.c | 105 |
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; } |