mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 21:01:47 +00:00
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:
parent
ba287c33cd
commit
3c7c91d0bd
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user