#include "command.h"
#include "prefix.h"
-#include "table.h"
+#include "agg_table.h"
#include "stream.h"
#include "memory.h"
#include "routemap.h"
struct zclient *zclient = NULL;
/* Send ECMP routes to zebra. */
-static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd)
+static void ripng_zebra_ipv6_send(struct agg_node *rp, uint8_t cmd)
{
- static struct in6_addr **nexthops = NULL;
- static ifindex_t *ifindexes = NULL;
- static unsigned int nexthops_len = 0;
-
struct list *list = (struct list *)rp->info;
- struct zapi_ipv6 api;
+ struct zapi_route api;
+ struct zapi_nexthop *api_nh;
struct listnode *listnode = NULL;
struct ripng_info *rinfo = NULL;
int count = 0;
+ memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_RIPNG;
- api.instance = 0;
- api.flags = 0;
- api.message = 0;
api.safi = SAFI_UNICAST;
-
- if (nexthops_len < listcount(list)) {
- nexthops_len = listcount(list);
- nexthops = XREALLOC(MTYPE_TMP, nexthops,
- nexthops_len * sizeof(struct in6_addr *));
- ifindexes = XREALLOC(MTYPE_TMP, ifindexes,
- nexthops_len * sizeof(unsigned int));
- }
+ api.prefix = rp->p;
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
- SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX);
for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
- nexthops[count] = &rinfo->nexthop;
- ifindexes[count] = rinfo->ifindex;
+ if (count >= MULTIPATH_NUM)
+ break;
+ api_nh = &api.nexthops[count];
+ api_nh->vrf_id = VRF_DEFAULT;
+ api_nh->gate.ipv6 = rinfo->nexthop;
+ api_nh->ifindex = rinfo->ifindex;
+ api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
count++;
- if (cmd == ZEBRA_IPV6_ROUTE_ADD)
+ if (cmd == ZEBRA_ROUTE_ADD)
SET_FLAG(rinfo->flags, RIPNG_RTF_FIB);
else
UNSET_FLAG(rinfo->flags, RIPNG_RTF_FIB);
}
- api.nexthop = nexthops;
api.nexthop_num = count;
- api.ifindex = ifindexes;
- api.ifindex_num = count;
rinfo = listgetdata(listhead(list));
api.tag = rinfo->tag;
}
- zapi_ipv6_route(cmd, zclient, (struct prefix_ipv6 *)&rp->p, NULL, &api);
+ zclient_route_send(cmd, zclient, &api);
if (IS_RIPNG_DEBUG_ZEBRA) {
if (ripng->ecmp)
zlog_debug("%s: %s/%d nexthops %d",
- (cmd == ZEBRA_IPV6_ROUTE_ADD)
+ (cmd == ZEBRA_ROUTE_ADD)
? "Install into zebra"
: "Delete from zebra",
inet6_ntoa(rp->p.u.prefix6), rp->p.prefixlen,
count);
else
- zlog_debug("%s: %s/%d",
- (cmd == ZEBRA_IPV6_ROUTE_ADD)
- ? "Install into zebra"
- : "Delete from zebra",
- inet6_ntoa(rp->p.u.prefix6),
- rp->p.prefixlen);
+ zlog_debug(
+ "%s: %s/%d",
+ (cmd == ZEBRA_ROUTE_ADD) ? "Install into zebra"
+ : "Delete from zebra",
+ inet6_ntoa(rp->p.u.prefix6), rp->p.prefixlen);
}
}
/* Add/update ECMP routes to zebra. */
-void ripng_zebra_ipv6_add(struct route_node *rp)
+void ripng_zebra_ipv6_add(struct agg_node *rp)
{
- ripng_zebra_ipv6_send(rp, ZEBRA_IPV6_ROUTE_ADD);
+ ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_ADD);
}
/* Delete ECMP routes from zebra. */
-void ripng_zebra_ipv6_delete(struct route_node *rp)
+void ripng_zebra_ipv6_delete(struct agg_node *rp)
{
- ripng_zebra_ipv6_send(rp, ZEBRA_IPV6_ROUTE_DELETE);
+ ripng_zebra_ipv6_send(rp, ZEBRA_ROUTE_DELETE);
}
/* Zebra route add and delete treatment. */
-static int ripng_zebra_read_ipv6(int command, struct zclient *zclient,
- zebra_size_t length, vrf_id_t vrf_id)
+static int ripng_zebra_read_route(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
{
- struct stream *s;
- struct zapi_ipv6 api;
- unsigned long ifindex;
+ struct zapi_route api;
struct in6_addr nexthop;
- struct prefix_ipv6 p, src_p;
-
- s = zclient->ibuf;
- ifindex = 0;
- memset(&nexthop, 0, sizeof(struct in6_addr));
-
- /* Type, flags, message. */
- api.type = stream_getc(s);
- api.instance = stream_getw(s);
- api.flags = stream_getl(s);
- api.message = stream_getc(s);
-
- /* IPv6 prefix. */
- memset(&p, 0, sizeof(struct prefix_ipv6));
- p.family = AF_INET6;
- p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc(s));
- stream_get(&p.prefix, s, PSIZE(p.prefixlen));
-
- memset(&src_p, 0, sizeof(struct prefix_ipv6));
- src_p.family = AF_INET6;
- if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
- src_p.prefixlen = stream_getc(s);
- stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen));
- }
+ unsigned long ifindex;
- if (src_p.prefixlen)
- /* we completely ignore srcdest routes for now. */
- return 0;
+ if (zapi_route_decode(zclient->ibuf, &api) < 0)
+ return -1;
- /* Nexthop, ifindex, distance, metric. */
- if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) {
- api.nexthop_num = stream_getc(s);
- stream_get(&nexthop, s, 16);
- }
- if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) {
- api.ifindex_num = stream_getc(s);
- ifindex = stream_getl(s);
- }
- if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
- api.distance = stream_getc(s);
- else
- api.distance = 0;
- if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC))
- api.metric = stream_getl(s);
- else
- api.metric = 0;
+ /* we completely ignore srcdest routes for now. */
+ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
+ return 0;
- if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG))
- api.tag = stream_getl(s);
- else
- api.tag = 0;
+ nexthop = api.nexthops[0].gate.ipv6;
+ ifindex = api.nexthops[0].ifindex;
- if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
- ripng_redistribute_add(api.type, RIPNG_ROUTE_REDISTRIBUTE, &p,
+ if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
+ ripng_redistribute_add(api.type, RIPNG_ROUTE_REDISTRIBUTE,
+ (struct prefix_ipv6 *)&api.prefix,
ifindex, &nexthop, api.tag);
else
ripng_redistribute_delete(api.type, RIPNG_ROUTE_REDISTRIBUTE,
- &p, ifindex);
+ (struct prefix_ipv6 *)&api.prefix,
+ ifindex);
return 0;
}
void zebra_init(struct thread_master *master)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master);
- zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0);
+ zclient = zclient_new(master, &zclient_options_default);
+ zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs);
zclient->zebra_connected = ripng_zebra_connected;
zclient->interface_up = ripng_interface_up;
zclient->interface_delete = ripng_interface_delete;
zclient->interface_address_add = ripng_interface_address_add;
zclient->interface_address_delete = ripng_interface_address_delete;
- zclient->redistribute_route_ipv6_add = ripng_zebra_read_ipv6;
- zclient->redistribute_route_ipv6_del = ripng_zebra_read_ipv6;
+ zclient->redistribute_route_add = ripng_zebra_read_route;
+ zclient->redistribute_route_del = ripng_zebra_read_route;
/* Install command elements to ripng node */
install_element(RIPNG_NODE, &ripng_redistribute_type_cmd);