zebra: receive ZAPI IPv6 source prefix

Check and read the IPv6 source prefix on ZAPI messages, and pass it down
to the RIB functions (which do nothing with it yet.)  Since the RIB
functions now all have a new extra argument, this also updates the
kernel route read functions to supply NULL.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2014-04-24 17:41:43 +02:00 committed by Christian Franke
parent ba287c33cd
commit 3c7c91d0bd
9 changed files with 64 additions and 38 deletions

View File

@ -114,6 +114,7 @@ struct zclient
#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

View File

@ -201,11 +201,11 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
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)
@ -331,10 +331,10 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
/* 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",
@ -407,7 +407,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
#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)
@ -507,7 +507,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
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",

View File

@ -992,17 +992,17 @@ rtm_read (struct rt_msghdr *rtm)
*/
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)
{
@ -1034,18 +1034,18 @@ rtm_read (struct rt_msghdr *rtm)
*/
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);
}
}

View File

@ -519,7 +519,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
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]);
@ -541,7 +541,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
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);
}
}
}
@ -565,7 +565,7 @@ zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
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 */

View File

@ -342,17 +342,17 @@ extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib);
* 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);

View File

@ -238,7 +238,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
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
{
@ -296,7 +296,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
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)
@ -306,7 +306,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
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);
}
@ -431,7 +431,7 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
{
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
{
@ -490,12 +490,12 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
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)
@ -516,11 +516,11 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
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;

View File

@ -94,7 +94,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
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

View File

@ -2585,7 +2585,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id)
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;
@ -2674,8 +2674,8 @@ rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
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;
@ -2815,7 +2815,8 @@ rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
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)
{

View File

@ -1149,7 +1149,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
/* 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)
@ -1243,7 +1243,7 @@ zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
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;
}
@ -1378,7 +1378,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
/* 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++;
@ -1399,6 +1399,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
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];
@ -1426,6 +1427,17 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
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
@ -1500,7 +1512,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
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++;
@ -1521,6 +1533,7 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
union g_addr *pnexthop = NULL;
unsigned long ifindex;
struct prefix p;
struct prefix_ipv6 src_p, *src_pp;
s = client->ibuf;
ifindex = 0;
@ -1539,6 +1552,17 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
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))
{
@ -1582,10 +1606,10 @@ zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
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;