#define ZAPI_MESSAGE_METRIC 0x08
#define ZAPI_MESSAGE_TAG 0x10
#define ZAPI_MESSAGE_MTU 0x20
+#define ZAPI_MESSAGE_SRCPFX 0x40
/* Zserv protocol message header */
struct zserv_header
return;
rib_add (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, NULL, ifp->ifindex,
+ 0, 0, &p, NULL, NULL, NULL, ifp->ifindex,
RT_TABLE_MAIN, ifp->metric, 0, 0);
rib_add (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, NULL, ifp->ifindex,
+ 0, 0, &p, NULL, NULL, NULL, ifp->ifindex,
RT_TABLE_MAIN, ifp->metric, 0, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
/* Same logic as for connected_up_ipv4(): push the changes into the head. */
rib_delete (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, ifp->ifindex, 0);
+ 0, 0, &p, NULL, NULL, ifp->ifindex, 0);
rib_delete (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, ifp->ifindex, 0);
+ 0, 0, &p, NULL, NULL, ifp->ifindex, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug ("%u: IF %s IPv4 address down, scheduling RIB processing",
#endif
rib_add (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, NULL, ifp->ifindex,
+ 0, 0, &p, NULL, NULL, NULL, ifp->ifindex,
RT_TABLE_MAIN, ifp->metric, 0, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
return;
rib_delete (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, ifp->ifindex, 0);
+ 0, 0, &p, NULL, NULL, ifp->ifindex, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing",
*/
if (rtm->rtm_type == RTM_CHANGE)
rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, NULL, 0, 0);
+ 0, zebra_flags, &p, NULL, NULL, 0, 0);
union g_addr ggate = { .ipv4 = gate.sin.sin_addr };
if (rtm->rtm_type == RTM_GET
|| rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
- &p, &ggate, NULL, 0, 0, 0, 0, 0);
+ &p, NULL, &ggate, NULL, 0, 0, 0, 0, 0);
else
rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, &ggate, 0, 0);
+ 0, zebra_flags, &p, NULL, &ggate, 0, 0);
}
if (dest.sa.sa_family == AF_INET6)
{
*/
if (rtm->rtm_type == RTM_CHANGE)
rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, NULL, 0, 0);
+ 0, zebra_flags, &p, NULL, NULL, 0, 0);
union g_addr ggate = { .ipv6 = gate.sin6.sin6_addr };
if (rtm->rtm_type == RTM_GET
|| rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
rib_add (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, &ggate, NULL, ifindex,
+ 0, zebra_flags, &p, NULL, &ggate, NULL, ifindex,
0, 0, 0, 0);
else
rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, &ggate, ifindex, 0);
+ 0, zebra_flags, &p, NULL, &ggate, ifindex, 0);
}
}
gate = (union g_addr *)&nhop->gate.ipv4;
rib_add (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE,
- rib->table, 0, &p, gate, (union g_addr *)&nhop->src.ipv4,
+ rib->table, 0, &p, NULL, gate, (union g_addr *)&nhop->src.ipv4,
nhop->ifindex, zebrad.rtm_table_default,
rib->metric, rib->mtu,
zebra_import_table_distance[AFI_IP][rib->table]);
for (nhop = rib->nexthop; nhop; nhop = nhop->next)
rib_copy_nexthops(newrib, nhop);
- rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, newrib);
+ rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, NULL, newrib);
}
}
}
p.u.prefix4 = rn->p.u.prefix4;
rib_delete (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE,
- rib->table, rib->flags, &p, NULL,
+ rib->table, rib->flags, &p, NULL, NULL,
0, zebrad.rtm_table_default);
}
/* DD: Add IPv6 code */
* also implicitly withdraw equal prefix of same type. */
extern int rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
- union g_addr *gate, union g_addr *src,
+ struct prefix_ipv6 *src_p, union g_addr *gate, union g_addr *src,
ifindex_t ifindex, u_int32_t table_id,
u_int32_t, u_int32_t, u_char);
extern int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *,
- struct rib *);
+ struct prefix_ipv6 *src_p, struct rib *);
extern int rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
- union g_addr *gate, ifindex_t ifindex,
- u_int32_t table_id);
+ struct prefix_ipv6 *src_p, union g_addr *gate,
+ ifindex_t ifindex, u_int32_t table_id);
extern struct rib *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *,
struct route_node **rn_out);
if (!tb[RTA_MULTIPATH])
rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, flags, &p, gate, src, index,
+ 0, flags, &p, NULL, gate, src, index,
table, metric, mtu, 0);
else
{
if (rib->nexthop_num == 0)
XFREE (MTYPE_RIB, rib);
else
- rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
+ rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib);
}
}
if (rtm->rtm_family == AF_INET6)
p.prefixlen = rtm->rtm_dst_len;
rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, flags, &p, gate, src, index,
+ 0, flags, &p, NULL, gate, src, index,
table, metric, mtu, 0);
}
{
if (!tb[RTA_MULTIPATH])
rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, 0, &p, gate, src, index,
+ 0, 0, &p, NULL, gate, src, index,
table, metric, mtu, 0);
else
{
if (rib->nexthop_num == 0)
XFREE (MTYPE_RIB, rib);
else
- rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
+ rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib);
}
}
else
rib_delete (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
- &p, gate, index, table);
+ &p, NULL, gate, index, table);
}
if (rtm->rtm_family == AF_INET6)
if (h->nlmsg_type == RTM_NEWROUTE)
rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, 0, &p, gate, src, index,
+ 0, 0, &p, NULL, gate, src, index,
table, metric, mtu, 0);
else
rib_delete (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, gate, index, table);
+ 0, zebra_flags, &p, NULL, gate, index, table);
}
return 0;
ggateway = (union g_addr *)&gateway;
rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
- zebra_flags, &prefix, ggateway, NULL, 0, 0, 0, 0, 0);
+ zebra_flags, &prefix, NULL, ggateway, NULL, 0, 0, 0, 0, 0);
}
void
int
rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
- struct rib *rib)
+ struct prefix_ipv6 *src_p, struct rib *rib)
{
struct route_table *table;
struct route_node *rn;
int
rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
- int flags, struct prefix *p, union g_addr *gate, ifindex_t ifindex,
- u_int32_t table_id)
+ int flags, struct prefix *p, struct prefix_ipv6 *src_p,
+ union g_addr *gate, ifindex_t ifindex, u_int32_t table_id)
{
struct route_table *table;
struct route_node *rn;
int
rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
- union g_addr *gate, union g_addr *src, ifindex_t ifindex,
+ struct prefix_ipv6 *src_p, union g_addr *gate,
+ union g_addr *src, ifindex_t ifindex,
u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
u_char distance)
{
/* Table */
rib->table = zvrf->table_id;
- ret = rib_add_multipath (AFI_IP, safi, &p, rib);
+ ret = rib_add_multipath (AFI_IP, safi, &p, NULL, rib);
/* Stats */
if (ret > 0)
table_id = zvrf->table_id;
rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance,
- api.flags, &p, nexthop_p, ifindex, table_id);
+ api.flags, &p, NULL, nexthop_p, ifindex, table_id);
client->v4_route_del_cnt++;
return 0;
}
/* Table */
rib->table = zvrf->table_id;
- ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
+ ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, rib);
/* Stats */
if (ret > 0)
client->v4_route_add_cnt++;
u_char nexthop_num;
u_char nexthop_type;
struct prefix p;
+ struct prefix_ipv6 src_p, *src_pp;
safi_t safi;
static struct in6_addr nexthops[MULTIPATH_NUM];
static unsigned int ifindices[MULTIPATH_NUM];
p.prefixlen = stream_getc (s);
stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
+ if (CHECK_FLAG (message, ZAPI_MESSAGE_SRCPFX))
+ {
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ src_pp = &src_p;
+ }
+ else
+ src_pp = NULL;
+
/* We need to give nh-addr, nh-ifindex with the same next-hop object
* to the rib to ensure that IPv6 multipathing works; need to coalesce
* these. Clients should send the same number of paired set of
rib->vrf_id = zvrf_id (zvrf);
rib->table = zvrf->table_id;
- ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
+ ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, rib);
/* Stats */
if (ret > 0)
client->v6_route_add_cnt++;
union g_addr *pnexthop = NULL;
unsigned long ifindex;
struct prefix p;
+ struct prefix_ipv6 src_p, *src_pp;
s = client->ibuf;
ifindex = 0;
p.prefixlen = stream_getc (s);
stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
+ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
+ {
+ memset (&src_p, 0, sizeof (struct prefix_ipv6));
+ src_p.family = AF_INET6;
+ src_p.prefixlen = stream_getc (s);
+ stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
+ src_pp = &src_p;
+ }
+ else
+ src_pp = NULL;
+
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
- api.flags, &p, NULL, ifindex, client->rtm_table);
+ api.flags, &p, src_pp, NULL, ifindex, client->rtm_table);
else
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
- api.flags, &p, pnexthop, ifindex, client->rtm_table);
+ api.flags, &p, src_pp, pnexthop, ifindex, client->rtm_table);
client->v6_route_del_cnt++;
return 0;