mirror of
https://github.com/FRRouting/frr.git
synced 2025-05-01 05:57:15 +02:00
zebra: refactor rib_add_ipv[4|6]_multipath
The rib_add_ipv[4|6]_multipath functions are functionally equivalent. Refactor to 1 function. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
3b1098beed
commit
b4c034b033
|
@ -374,7 +374,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
|
||||||
apply_mask (&p);
|
apply_mask (&p);
|
||||||
|
|
||||||
#ifndef LINUX
|
#ifndef LINUX
|
||||||
/* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */
|
/* XXX: It is already done by rib_bogus_ipv6 within rib_add */
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
|
if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -598,7 +598,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char
|
||||||
for (nhop = rib->nexthop; nhop; nhop = nhop->next)
|
for (nhop = rib->nexthop; nhop; nhop = nhop->next)
|
||||||
rib_copy_nexthops(newrib, nhop);
|
rib_copy_nexthops(newrib, nhop);
|
||||||
|
|
||||||
rib_add_ipv4_multipath((struct prefix_ipv4 *)&p, newrib, SAFI_UNICAST);
|
rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, newrib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
zebra/rib.h
15
zebra/rib.h
|
@ -336,7 +336,7 @@ extern int rib_install_kernel (struct route_node *rn, struct rib *rib, int updat
|
||||||
extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib);
|
extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib);
|
||||||
|
|
||||||
/* NOTE:
|
/* NOTE:
|
||||||
* All rib_add_ipv[46]* functions will not just add prefix into RIB, but
|
* All rib_add function will not just add prefix into RIB, but
|
||||||
* also implicitly withdraw equal prefix of same type. */
|
* 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,
|
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,
|
u_short instance, int flags, struct prefix *p,
|
||||||
|
@ -344,7 +344,8 @@ extern int rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||||
ifindex_t ifindex, u_int32_t table_id,
|
ifindex_t ifindex, u_int32_t table_id,
|
||||||
u_int32_t, u_int32_t, u_char);
|
u_int32_t, u_int32_t, u_char);
|
||||||
|
|
||||||
extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *, safi_t);
|
extern int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *,
|
||||||
|
struct rib *);
|
||||||
|
|
||||||
extern int rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
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,
|
u_short instance, int flags, struct prefix *p,
|
||||||
|
@ -367,20 +368,10 @@ extern void rib_init (void);
|
||||||
extern unsigned long rib_score_proto (u_char proto, u_short instance);
|
extern unsigned long rib_score_proto (u_char proto, u_short instance);
|
||||||
extern void rib_queue_add (struct route_node *rn);
|
extern void rib_queue_add (struct route_node *rn);
|
||||||
|
|
||||||
extern int
|
|
||||||
rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
|
||||||
struct in6_addr *gate, ifindex_t ifindex, vrf_id_t vrf_id,
|
|
||||||
u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
|
|
||||||
u_char distance, safi_t safi);
|
|
||||||
|
|
||||||
extern struct rib *rib_lookup_ipv6 (struct in6_addr *, vrf_id_t);
|
extern struct rib *rib_lookup_ipv6 (struct in6_addr *, vrf_id_t);
|
||||||
|
|
||||||
extern struct route_table *rib_table_ipv6;
|
extern struct route_table *rib_table_ipv6;
|
||||||
|
|
||||||
extern int
|
|
||||||
rib_add_ipv6_multipath (struct prefix *, struct rib *, safi_t,
|
|
||||||
ifindex_t);
|
|
||||||
|
|
||||||
extern int rib_gc_dest (struct route_node *rn);
|
extern int rib_gc_dest (struct route_node *rn);
|
||||||
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
|
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
|
||||||
|
|
||||||
|
|
|
@ -1017,7 +1017,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
if (rib->nexthop_num == 0)
|
if (rib->nexthop_num == 0)
|
||||||
XFREE (MTYPE_RIB, rib);
|
XFREE (MTYPE_RIB, rib);
|
||||||
else
|
else
|
||||||
rib_add_ipv4_multipath ((struct prefix_ipv4 *)&p, rib, SAFI_UNICAST);
|
rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rtm->rtm_family == AF_INET6)
|
if (rtm->rtm_family == AF_INET6)
|
||||||
|
@ -1252,7 +1252,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
if (rib->nexthop_num == 0)
|
if (rib->nexthop_num == 0)
|
||||||
XFREE (MTYPE_RIB, rib);
|
XFREE (MTYPE_RIB, rib);
|
||||||
else
|
else
|
||||||
rib_add_ipv4_multipath ((struct prefix_ipv4 *)&p, rib, SAFI_UNICAST);
|
rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -2517,21 +2517,31 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
|
rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p,
|
||||||
|
struct rib *rib)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct rib *same;
|
struct rib *same;
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int family;
|
||||||
|
|
||||||
|
if (!rib)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (p->family == AF_INET)
|
||||||
|
family = AFI_IP;
|
||||||
|
else
|
||||||
|
family = AFI_IP6;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = zebra_vrf_table_with_table_id (AFI_IP, safi, rib->vrf_id, rib->table);
|
table = zebra_vrf_table_with_table_id (family, safi, rib->vrf_id, rib->table);
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Make it sure prefixlen is applied to the prefix. */
|
/* Make it sure prefixlen is applied to the prefix. */
|
||||||
apply_mask_ipv4 (p);
|
apply_mask (p);
|
||||||
|
|
||||||
/* Set default distance by route type. */
|
/* Set default distance by route type. */
|
||||||
if (rib->distance == 0)
|
if (rib->distance == 0)
|
||||||
|
@ -2545,7 +2555,7 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup route node.*/
|
/* Lookup route node.*/
|
||||||
rn = route_node_get (table, (struct prefix *) p);
|
rn = route_node_get (table, p);
|
||||||
|
|
||||||
/* If same type of route are installed, treat it as a implicit
|
/* If same type of route are installed, treat it as a implicit
|
||||||
withdraw. */
|
withdraw. */
|
||||||
|
@ -2571,7 +2581,7 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
|
||||||
char buf[INET6_ADDRSTRLEN];
|
char buf[INET6_ADDRSTRLEN];
|
||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
{
|
{
|
||||||
inet_ntop (p->family, &p->prefix, buf, INET6_ADDRSTRLEN);
|
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
|
||||||
zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
|
zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
|
||||||
"existing %p",
|
"existing %p",
|
||||||
rib->vrf_id, buf, p->prefixlen, (void *)rn,
|
rib->vrf_id, buf, p->prefixlen, (void *)rn,
|
||||||
|
@ -2865,119 +2875,6 @@ rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
|
|
||||||
ifindex_t ifindex)
|
|
||||||
{
|
|
||||||
struct route_table *table;
|
|
||||||
struct route_node *rn;
|
|
||||||
struct rib *same = NULL;
|
|
||||||
struct nexthop *nexthop;
|
|
||||||
int ret = 0;
|
|
||||||
int family;
|
|
||||||
|
|
||||||
if (!rib)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (p->family == AF_INET)
|
|
||||||
family = AFI_IP;
|
|
||||||
else
|
|
||||||
family = AFI_IP6;
|
|
||||||
|
|
||||||
/* Lookup table. */
|
|
||||||
table = zebra_vrf_table_with_table_id (family, safi, rib->vrf_id, rib->table);
|
|
||||||
if (! table)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (p->family == AF_INET)
|
|
||||||
{
|
|
||||||
/* Make it sure prefixlen is applied to the prefix. */
|
|
||||||
apply_mask_ipv4 ((struct prefix_ipv4 *)p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Make sure mask is applied. */
|
|
||||||
apply_mask_ipv6 ((struct prefix_ipv6 *)p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set default distance by route type. */
|
|
||||||
if (rib->distance == 0)
|
|
||||||
{
|
|
||||||
rib->distance = route_info[rib->type].distance;
|
|
||||||
|
|
||||||
/* iBGP distance is 200. */
|
|
||||||
if (rib->type == ZEBRA_ROUTE_BGP
|
|
||||||
&& CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP))
|
|
||||||
rib->distance = 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lookup route node.*/
|
|
||||||
rn = route_node_get (table, (struct prefix *) p);
|
|
||||||
|
|
||||||
/* If same type of route are installed, treat it as a implicit
|
|
||||||
withdraw. */
|
|
||||||
RNODE_FOREACH_RIB (rn, same) {
|
|
||||||
if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (same->type != rib->type) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (same->instance != rib->instance) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (same->table != rib->table) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (same->type != ZEBRA_ROUTE_CONNECT) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if ((nexthop = same->nexthop) &&
|
|
||||||
nexthop->type == NEXTHOP_TYPE_IFINDEX &&
|
|
||||||
nexthop->ifindex == ifindex) {
|
|
||||||
same->refcnt++;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If this route is kernel route, set FIB flag to the route. */
|
|
||||||
if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT) {
|
|
||||||
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) {
|
|
||||||
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Link new rib to node.*/
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB)
|
|
||||||
{
|
|
||||||
char buf[INET6_ADDRSTRLEN];
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB)
|
|
||||||
{
|
|
||||||
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
|
|
||||||
zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d) "
|
|
||||||
"existing %p",
|
|
||||||
rib->vrf_id, buf, p->prefixlen, rn, rib, rib->type, same);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
|
||||||
rib_dump ((struct prefix *)p, rib);
|
|
||||||
}
|
|
||||||
rib_addnode (rn, rib, 1);
|
|
||||||
ret = 1;
|
|
||||||
|
|
||||||
/* Free implicit route.*/
|
|
||||||
if (same)
|
|
||||||
{
|
|
||||||
rib_delnode (rn, same);
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
route_unlock_node (rn);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Schedule routes of a particular table (address-family) based on event. */
|
/* Schedule routes of a particular table (address-family) based on event. */
|
||||||
static void
|
static void
|
||||||
rib_update_table (struct route_table *table, rib_update_event_t event)
|
rib_update_table (struct route_table *table, rib_update_event_t event)
|
||||||
|
|
|
@ -1186,7 +1186,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct rib *rib;
|
struct rib *rib;
|
||||||
struct prefix_ipv4 p;
|
struct prefix p;
|
||||||
u_char message;
|
u_char message;
|
||||||
struct in_addr nexthop;
|
struct in_addr nexthop;
|
||||||
u_char nexthop_num;
|
u_char nexthop_num;
|
||||||
|
@ -1214,7 +1214,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||||
memset (&p, 0, sizeof (struct prefix_ipv4));
|
memset (&p, 0, sizeof (struct prefix_ipv4));
|
||||||
p.family = AF_INET;
|
p.family = AF_INET;
|
||||||
p.prefixlen = stream_getc (s);
|
p.prefixlen = stream_getc (s);
|
||||||
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
|
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
|
||||||
|
|
||||||
/* VRF ID */
|
/* VRF ID */
|
||||||
rib->vrf_id = zvrf->vrf_id;
|
rib->vrf_id = zvrf->vrf_id;
|
||||||
|
@ -1276,7 +1276,7 @@ zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||||
/* Table */
|
/* Table */
|
||||||
rib->table = zvrf->table_id;
|
rib->table = zvrf->table_id;
|
||||||
|
|
||||||
ret = rib_add_ipv4_multipath (&p, rib, safi);
|
ret = rib_add_multipath (AFI_IP, safi, &p, rib);
|
||||||
|
|
||||||
/* Stats */
|
/* Stats */
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
|
@ -1427,8 +1427,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
|
||||||
u_char message;
|
u_char message;
|
||||||
u_char nexthop_num;
|
u_char nexthop_num;
|
||||||
u_char nexthop_type;
|
u_char nexthop_type;
|
||||||
unsigned long ifindex;
|
struct prefix p;
|
||||||
struct prefix_ipv4 p;
|
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
static struct in6_addr nexthops[MULTIPATH_NUM];
|
static struct in6_addr nexthops[MULTIPATH_NUM];
|
||||||
static unsigned int ifindices[MULTIPATH_NUM];
|
static unsigned int ifindices[MULTIPATH_NUM];
|
||||||
|
@ -1437,7 +1436,6 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
|
||||||
/* Get input stream. */
|
/* Get input stream. */
|
||||||
s = client->ibuf;
|
s = client->ibuf;
|
||||||
|
|
||||||
ifindex = 0;
|
|
||||||
memset (&nexthop, 0, sizeof (struct in6_addr));
|
memset (&nexthop, 0, sizeof (struct in6_addr));
|
||||||
|
|
||||||
/* Allocate new rib. */
|
/* Allocate new rib. */
|
||||||
|
@ -1455,7 +1453,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
|
||||||
memset (&p, 0, sizeof (struct prefix_ipv4));
|
memset (&p, 0, sizeof (struct prefix_ipv4));
|
||||||
p.family = AF_INET;
|
p.family = AF_INET;
|
||||||
p.prefixlen = stream_getc (s);
|
p.prefixlen = stream_getc (s);
|
||||||
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
|
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
|
||||||
|
|
||||||
/* VRF ID */
|
/* VRF ID */
|
||||||
rib->vrf_id = zvrf->vrf_id;
|
rib->vrf_id = zvrf->vrf_id;
|
||||||
|
@ -1536,7 +1534,7 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct
|
||||||
/* Table */
|
/* Table */
|
||||||
rib->table = zvrf->table_id;
|
rib->table = zvrf->table_id;
|
||||||
|
|
||||||
ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
|
ret = rib_add_multipath (AFI_IP6, safi, &p, rib);
|
||||||
/* Stats */
|
/* Stats */
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
client->v4_route_add_cnt++;
|
client->v4_route_add_cnt++;
|
||||||
|
@ -1556,8 +1554,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||||
u_char message;
|
u_char message;
|
||||||
u_char nexthop_num;
|
u_char nexthop_num;
|
||||||
u_char nexthop_type;
|
u_char nexthop_type;
|
||||||
unsigned long ifindex;
|
struct prefix p;
|
||||||
struct prefix_ipv6 p;
|
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
static struct in6_addr nexthops[MULTIPATH_NUM];
|
static struct in6_addr nexthops[MULTIPATH_NUM];
|
||||||
static unsigned int ifindices[MULTIPATH_NUM];
|
static unsigned int ifindices[MULTIPATH_NUM];
|
||||||
|
@ -1566,7 +1563,6 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||||
/* Get input stream. */
|
/* Get input stream. */
|
||||||
s = client->ibuf;
|
s = client->ibuf;
|
||||||
|
|
||||||
ifindex = 0;
|
|
||||||
memset (&nexthop, 0, sizeof (struct in6_addr));
|
memset (&nexthop, 0, sizeof (struct in6_addr));
|
||||||
|
|
||||||
/* Allocate new rib. */
|
/* Allocate new rib. */
|
||||||
|
@ -1584,7 +1580,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||||
memset (&p, 0, sizeof (struct prefix_ipv6));
|
memset (&p, 0, sizeof (struct prefix_ipv6));
|
||||||
p.family = AF_INET6;
|
p.family = AF_INET6;
|
||||||
p.prefixlen = stream_getc (s);
|
p.prefixlen = stream_getc (s);
|
||||||
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
|
stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
|
||||||
|
|
||||||
/* We need to give nh-addr, nh-ifindex with the same next-hop object
|
/* 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
|
* to the rib to ensure that IPv6 multipathing works; need to coalesce
|
||||||
|
@ -1660,7 +1656,7 @@ zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
||||||
rib->vrf_id = zvrf->vrf_id;
|
rib->vrf_id = zvrf->vrf_id;
|
||||||
rib->table = zvrf->table_id;
|
rib->table = zvrf->table_id;
|
||||||
|
|
||||||
ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
|
ret = rib_add_multipath (AFI_IP, safi, &p, rib);
|
||||||
/* Stats */
|
/* Stats */
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
client->v6_route_add_cnt++;
|
client->v6_route_add_cnt++;
|
||||||
|
|
Loading…
Reference in a new issue