apply_mask (&p);
#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))
return;
#endif
for (nhop = rib->nexthop; nhop; nhop = nhop->next)
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);
}
}
}
extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib);
/* 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. */
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,
ifindex_t ifindex, u_int32_t table_id,
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,
u_short instance, int flags, struct prefix *p,
extern unsigned long rib_score_proto (u_char proto, u_short instance);
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 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 struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
if (rib->nexthop_num == 0)
XFREE (MTYPE_RIB, rib);
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 (rib->nexthop_num == 0)
XFREE (MTYPE_RIB, rib);
else
- rib_add_ipv4_multipath ((struct prefix_ipv4 *)&p, rib, SAFI_UNICAST);
+ rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, rib);
}
}
else
}
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_node *rn;
struct rib *same;
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 (AFI_IP, safi, rib->vrf_id, rib->table);
+ table = zebra_vrf_table_with_table_id (family, safi, rib->vrf_id, rib->table);
if (! table)
return 0;
/* Make it sure prefixlen is applied to the prefix. */
- apply_mask_ipv4 (p);
+ apply_mask (p);
/* Set default distance by route type. */
if (rib->distance == 0)
}
/* 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
withdraw. */
char buf[INET6_ADDRSTRLEN];
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) "
"existing %p",
rib->vrf_id, buf, p->prefixlen, (void *)rn,
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. */
static void
rib_update_table (struct route_table *table, rib_update_event_t event)
{
int i;
struct rib *rib;
- struct prefix_ipv4 p;
+ struct prefix p;
u_char message;
struct in_addr nexthop;
u_char nexthop_num;
memset (&p, 0, sizeof (struct prefix_ipv4));
p.family = AF_INET;
p.prefixlen = stream_getc (s);
- stream_get (&p.prefix, s, PSIZE (p.prefixlen));
+ stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
/* VRF ID */
rib->vrf_id = zvrf->vrf_id;
/* Table */
rib->table = zvrf->table_id;
- ret = rib_add_ipv4_multipath (&p, rib, safi);
+ ret = rib_add_multipath (AFI_IP, safi, &p, rib);
/* Stats */
if (ret > 0)
u_char message;
u_char nexthop_num;
u_char nexthop_type;
- unsigned long ifindex;
- struct prefix_ipv4 p;
+ struct prefix p;
safi_t safi;
static struct in6_addr nexthops[MULTIPATH_NUM];
static unsigned int ifindices[MULTIPATH_NUM];
/* Get input stream. */
s = client->ibuf;
- ifindex = 0;
memset (&nexthop, 0, sizeof (struct in6_addr));
/* Allocate new rib. */
memset (&p, 0, sizeof (struct prefix_ipv4));
p.family = AF_INET;
p.prefixlen = stream_getc (s);
- stream_get (&p.prefix, s, PSIZE (p.prefixlen));
+ stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
/* VRF ID */
rib->vrf_id = zvrf->vrf_id;
/* Table */
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 */
if (ret > 0)
client->v4_route_add_cnt++;
u_char message;
u_char nexthop_num;
u_char nexthop_type;
- unsigned long ifindex;
- struct prefix_ipv6 p;
+ struct prefix p;
safi_t safi;
static struct in6_addr nexthops[MULTIPATH_NUM];
static unsigned int ifindices[MULTIPATH_NUM];
/* Get input stream. */
s = client->ibuf;
- ifindex = 0;
memset (&nexthop, 0, sizeof (struct in6_addr));
/* Allocate new rib. */
memset (&p, 0, sizeof (struct prefix_ipv6));
p.family = AF_INET6;
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
* to the rib to ensure that IPv6 multipathing works; need to coalesce
rib->vrf_id = zvrf->vrf_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 */
if (ret > 0)
client->v6_route_add_cnt++;