From: Donald Sharp Date: Sun, 4 Jun 2017 23:14:44 +0000 (-0400) Subject: lib: Add zapi_route function. X-Git-Tag: reindent-master-before~74^2~8 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=657cde1267796d2c00bd1df81598b8705ef69cc1;p=mirror_frr.git lib: Add zapi_route function. Allow routing protocols to call one function to add/delete routes into zebra. Future commits will start adding this code to individual routing protocols. Why are we doing this? Well the zapi_ipv[4|6]_route functions are fundamentally broken in their ability to pass down anything but NEXTHOP_TYPE_IFINDEX or NEXTHOP_TYPE_IPV[4|6] and we need the ability to pass down a bit more information. Signed-off-by: Donald Sharp --- diff --git a/lib/zclient.c b/lib/zclient.c index a53e8112c..801769b96 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -977,6 +977,98 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, return zclient_send_message(zclient); } +int +zapi_route (u_char cmd, struct zclient *zclient, struct prefix *p, + struct prefix_ipv6 *src_p, struct zapi_route *api) +{ + int i; + int psize; + struct stream *s; + + /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL */ + assert (!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p); + + /* Reset stream. */ + s = zclient->obuf; + stream_reset (s); + + zclient_create_header (s, cmd, api->vrf_id); + + /* Put type and nexthop. */ + stream_putc (s, api->type); + stream_putw (s, api->instance); + stream_putl (s, api->flags); + stream_putc (s, api->message); + stream_putw (s, api->safi); + + /* Put prefix information. */ + psize = PSIZE (p->prefixlen); + stream_putc (s, p->prefixlen); + stream_write (s, (u_char *)&p->u.prefix, psize); + + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_SRCPFX)) + { + psize = PSIZE (src_p->prefixlen); + stream_putc (s, src_p->prefixlen); + stream_write (s, (u_char *)&src_p->prefix, psize); + } + + /* Nexthop, ifindex, distance and metric information. */ + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) + { + stream_putc (s, api->nexthop_num); + + for (i = 0; i < api->nexthop_num; i++) + { + stream_putc (s, api->nexthop[i]->type); + switch (api->nexthop[i]->type) + { + case NEXTHOP_TYPE_BLACKHOLE: + break; + case NEXTHOP_TYPE_IPV4: + stream_put_in_addr (s, &api->nexthop[i]->gate.ipv4); + + /* For labeled-unicast, each nexthop is followed by label. */ + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL)) + stream_putl (s, api->nexthop[i]->nh_label->label[0]); + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + stream_put_in_addr (s, &api->nexthop[i]->gate.ipv4); + stream_putl (s, api->nexthop[i]->ifindex); + break; + case NEXTHOP_TYPE_IFINDEX: + stream_putl (s, api->nexthop[i]->ifindex); + break; + case NEXTHOP_TYPE_IPV6: + stream_write (s, (u_char *)&api->nexthop[i]->gate.ipv6, 16); + + /* For labeled-unicast, each nexthop is followed by label. */ + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_LABEL)) + stream_putl (s, api->nexthop[i]->nh_label->label[0]); + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + stream_write (s, (u_char *)&api->nexthop[i]->gate.ipv6, 16); + stream_putl (s, api->nexthop[i]->ifindex); + break; + } + } + } + + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) + stream_putc (s, api->distance); + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) + stream_putl (s, api->metric); + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG)) + stream_putl (s, api->tag); + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU)) + stream_putl (s, api->mtu); + + /* Put length at the first point of the stream. */ + stream_putw_at (s, 0, stream_get_endp (s)); + + return zclient_send_message(zclient); +} + /* * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will diff --git a/lib/zclient.h b/lib/zclient.h index 847ac3b67..59412fdd4 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -192,6 +192,31 @@ struct zserv_header uint16_t command; }; +struct zapi_route +{ + u_char type; + u_short instance; + + u_int32_t flags; + + u_char message; + + safi_t safi; + + u_char nexthop_num; + struct nexthop **nexthop; + + u_char distance; + + u_int32_t metric; + + route_tag_t tag; + + u_int32_t mtu; + + vrf_id_t vrf_id; +}; + /* Zebra IPv4 route message API. */ struct zapi_ipv4 { @@ -323,5 +348,8 @@ extern int zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct zapi_ipv6 *api); extern int zapi_ipv4_route_ipv6_nexthop (u_char, struct zclient *, struct prefix_ipv4 *, struct zapi_ipv6 *); +extern int zapi_route (u_char cmd, struct zclient *zclient, + struct prefix *p, struct prefix_ipv6 *src_p, + struct zapi_route *api); #endif /* _ZEBRA_ZCLIENT_H */