summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/memtypes.c3
-rw-r--r--lib/nexthop.h2
-rw-r--r--zebra/rib.h79
-rw-r--r--zebra/zebra_rib.c444
-rw-r--r--zebra/zebra_vty.c36
5 files changed, 192 insertions, 372 deletions
diff --git a/lib/memtypes.c b/lib/memtypes.c
index fc50443600..828820f309 100644
--- a/lib/memtypes.c
+++ b/lib/memtypes.c
@@ -85,8 +85,7 @@ struct memory_list memory_list_zebra[] =
{ MTYPE_NEXTHOP, "Nexthop" },
{ MTYPE_RIB, "RIB" },
{ MTYPE_RIB_QUEUE, "RIB process work queue" },
- { MTYPE_STATIC_IPV4, "Static IPv4 route" },
- { MTYPE_STATIC_IPV6, "Static IPv6 route" },
+ { MTYPE_STATIC_ROUTE, "Static route" },
{ MTYPE_RIB_DEST, "RIB destination" },
{ MTYPE_RIB_TABLE_INFO, "RIB table info" },
{ MTYPE_RNH, "Nexthop tracking object" },
diff --git a/lib/nexthop.h b/lib/nexthop.h
index e92d97262c..6909775a06 100644
--- a/lib/nexthop.h
+++ b/lib/nexthop.h
@@ -27,9 +27,7 @@
union g_addr {
struct in_addr ipv4;
-#ifdef HAVE_IPV6
struct in6_addr ipv6;
-#endif /* HAVE_IPV6 */
};
enum nexthop_types_t
diff --git a/zebra/rib.h b/zebra/rib.h
index 25ab68df13..cd77db4df1 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -169,11 +169,11 @@ typedef struct rib_dest_t_
RIB_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), rib, next)
/* Static route information. */
-struct static_ipv4
+struct static_route
{
/* For linked list. */
- struct static_ipv4 *prev;
- struct static_ipv4 *next;
+ struct static_route *prev;
+ struct static_route *next;
/* VRF identifier. */
vrf_id_t vrf_id;
@@ -186,50 +186,22 @@ struct static_ipv4
/* Flag for this static route's type. */
u_char type;
-#define STATIC_IPV4_GATEWAY 1
-#define STATIC_IPV4_IFNAME 2
-#define STATIC_IPV4_BLACKHOLE 3
+#define STATIC_IPV4_GATEWAY 1
+#define STATIC_IPV4_IFNAME 2
+#define STATIC_IPV4_BLACKHOLE 3
+#define STATIC_IPV6_GATEWAY 4
+#define STATIC_IPV6_GATEWAY_IFNAME 5
+#define STATIC_IPV6_IFNAME 6
- /* Nexthop value. */
- union
- {
- struct in_addr ipv4;
- char *ifname;
- } gate;
-
- /* bit flags */
- u_char flags;
-/*
- see ZEBRA_FLAG_REJECT
- ZEBRA_FLAG_BLACKHOLE
- */
-};
-
-#ifdef HAVE_IPV6
-/* Static route information. */
-struct static_ipv6
-{
- /* For linked list. */
- struct static_ipv6 *prev;
- struct static_ipv6 *next;
-
- /* VRF identifier. */
- vrf_id_t vrf_id;
-
- /* Administrative distance. */
- u_char distance;
-
- /* Tag */
- u_short tag;
-
- /* Flag for this static route's type. */
- u_char type;
-#define STATIC_IPV6_GATEWAY 1
-#define STATIC_IPV6_GATEWAY_IFNAME 2
-#define STATIC_IPV6_IFNAME 3
-
- /* Nexthop value. */
- struct in6_addr ipv6;
+ /*
+ * Nexthop value.
+ *
+ * Under IPv4 addr and ifname are
+ * used independentyly.
+ * STATIC_IPV4_GATEWAY uses addr
+ * STATIC_IPV4_IFNAME uses ifname
+ */
+ union g_addr addr;
char *ifname;
/* bit flags */
@@ -239,7 +211,7 @@ struct static_ipv6
ZEBRA_FLAG_BLACKHOLE
*/
};
-#endif /* HAVE_IPV6 */
+
/* The following for loop allows to iterate over the nexthop
* structure of routes.
@@ -296,7 +268,7 @@ struct static_ipv6
#endif
#endif
-#if defined (HAVE_IPV6) && defined (RTADV)
+#if defined (RTADV)
/* Structure which hold status of router advertisement. */
struct rtadv
{
@@ -308,7 +280,7 @@ struct rtadv
struct thread *ra_read;
struct thread *ra_timer;
};
-#endif /* RTADV && HAVE_IPV6 */
+#endif /* RTADV */
#ifdef HAVE_NETLINK
/* Socket interface to kernel */
@@ -366,9 +338,9 @@ struct zebra_vrf
struct list *rid_lo_sorted_list;
struct prefix rid_user_assigned;
-#if defined (HAVE_IPV6) && defined (RTADV)
+#if defined (RTADV)
struct rtadv rtadv;
-#endif /* RTADV && HAVE_IPV6 */
+#endif /* RTADV */
};
/*
@@ -438,7 +410,6 @@ extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *,
#define ZEBRA_RIB_FOUND_CONNECTED 2
#define ZEBRA_RIB_NOTFOUND 3
-#ifdef HAVE_IPV6
extern struct nexthop *nexthop_ipv6_add (struct rib *, struct in6_addr *);
extern struct nexthop *nexthop_ipv6_ifindex_add (struct rib *rib,
struct in6_addr *ipv6, unsigned int ifindex);
@@ -448,7 +419,6 @@ extern struct nexthop *nexthop_ipv6_ifname_add (struct rib *rib,
extern int
rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
struct in6_addr *gate, unsigned int ifindex, int table);
-#endif /* HAVE_IPV6 */
extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id);
extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t);
@@ -498,7 +468,6 @@ extern int
static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
u_short tag, u_char distance, vrf_id_t vrf_id);
-#ifdef HAVE_IPV6
extern int
rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
@@ -529,8 +498,6 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
const char *ifname, u_short tag, u_char distance,
vrf_id_t vrf_id);
-#endif /* HAVE_IPV6 */
-
extern int rib_gc_dest (struct route_node *rn);
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index ffa3161f2b..0bb9b58118 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -139,7 +139,6 @@ zebra_check_addr (struct prefix *p)
|| IPV4_LINKLOCAL(addr))
return 0;
}
-#ifdef HAVE_IPV6
if (p->family == AF_INET6)
{
if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))
@@ -147,7 +146,6 @@ zebra_check_addr (struct prefix *p)
if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))
return 0;
}
-#endif /* HAVE_IPV6 */
return 1;
}
@@ -348,7 +346,6 @@ nexthop_ipv4_ifindex_ol_add (struct rib *rib, const struct in_addr *ipv4,
return nexthop;
}
-#ifdef HAVE_IPV6
struct nexthop *
nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
{
@@ -394,7 +391,6 @@ nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
return nexthop;
}
-#endif /* HAVE_IPV6 */
struct nexthop *
nexthop_blackhole_add (struct rib *rib)
@@ -650,7 +646,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
return 0;
}
-#ifdef HAVE_IPV6
/* If force flag is not set, do not modify falgs at all for uninstall
the route from FIB. */
static int
@@ -840,7 +835,6 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
}
return 0;
}
-#endif /* HAVE_IPV6 */
struct rib *
rib_match_ipv4 (struct in_addr addr, vrf_id_t vrf_id)
@@ -1026,7 +1020,6 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
return ZEBRA_RIB_NOTFOUND;
}
-#ifdef HAVE_IPV6
struct rib *
rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
{
@@ -1088,7 +1081,6 @@ rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
}
return NULL;
}
-#endif /* HAVE_IPV6 */
#define RIB_SYSTEM_ROUTE(R) \
((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
@@ -1153,7 +1145,6 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
else
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
break;
-#ifdef HAVE_IPV6
case NEXTHOP_TYPE_IPV6:
family = AFI_IP6;
if (nexthop_active_ipv6 (rib, nexthop, set, rn))
@@ -1181,7 +1172,6 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
}
break;
-#endif /* HAVE_IPV6 */
case NEXTHOP_TYPE_BLACKHOLE:
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
break;
@@ -1305,11 +1295,9 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, int update)
else
ret = kernel_add_ipv4 (&rn->p, rib);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
ret = kernel_add_ipv6 (&rn->p, rib);
break;
-#endif /* HAVE_IPV6 */
}
/* This condition is never met, if we are using rt_socket.c */
@@ -1339,11 +1327,9 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
case AF_INET:
ret = kernel_delete_ipv4 (&rn->p, rib);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
ret = kernel_delete_ipv6 (&rn->p, rib);
break;
-#endif /* HAVE_IPV6 */
}
for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
@@ -1781,10 +1767,8 @@ meta_queue_process_complete (struct work_queue *dummy)
{
zebra_evaluate_rnh(0, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL);
zebra_evaluate_rnh(0, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL);
-#ifdef HAVE_IPV6
zebra_evaluate_rnh(0, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL);
zebra_evaluate_rnh(0, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL);
-#endif /* HAVE_IPV6 */
}
/* Dispatch the meta queue by picking, processing and unlocking the next RN from
@@ -1967,7 +1951,7 @@ rib_queue_init (struct zebra_t *zebra)
* as a route_node will not be requeued, if already queued.
*
* RIBs are submitted via rib_addnode or rib_delnode which set minimal
- * state, or static_install_ipv{4,6} (when an existing RIB is updated)
+ * state, or static_install_route (when an existing RIB is updated)
* and then submit route_node to queue for best-path selection later.
* Order of add/delete state changes are preserved for any given RIB.
*
@@ -2678,7 +2662,7 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
/* Install static route into rib. */
static void
-static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
+static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
{
struct rib *rib;
struct route_node *rn;
@@ -2686,7 +2670,7 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
struct prefix nh_p;
/* Lookup table. */
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, si->vrf_id);
+ table = zebra_vrf_table (afi, safi, si->vrf_id);
if (! table)
return;
@@ -2712,19 +2696,32 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
route_unlock_node (rn);
switch (si->type)
{
- case STATIC_IPV4_GATEWAY:
- nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
- nh_p.family = AF_INET;
- nh_p.prefixlen = IPV4_MAX_BITLEN;
- nh_p.u.prefix4 = si->gate.ipv4;
- zebra_register_rnh_static_nh(&nh_p, rn);
- break;
- case STATIC_IPV4_IFNAME:
- nexthop_ifname_add (rib, si->gate.ifname);
- break;
- case STATIC_IPV4_BLACKHOLE:
- nexthop_blackhole_add (rib);
- break;
+ case STATIC_IPV4_GATEWAY:
+ nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
+ nh_p.family = AF_INET;
+ nh_p.prefixlen = IPV4_MAX_BITLEN;
+ nh_p.u.prefix4 = si->addr.ipv4;
+ zebra_register_rnh_static_nh(&nh_p, rn);
+ break;
+ case STATIC_IPV4_IFNAME:
+ nexthop_ifname_add (rib, si->ifname);
+ break;
+ case STATIC_IPV4_BLACKHOLE:
+ nexthop_blackhole_add (rib);
+ break;
+ case STATIC_IPV6_GATEWAY:
+ nexthop_ipv6_add (rib, &si->addr.ipv6);
+ nh_p.family = AF_INET6;
+ nh_p.prefixlen = IPV6_MAX_BITLEN;
+ nh_p.u.prefix6 = si->addr.ipv6;
+ zebra_register_rnh_static_nh(&nh_p, rn);
+ break;
+ case STATIC_IPV6_IFNAME:
+ nexthop_ifname_add (rib, si->ifname);
+ break;
+ case STATIC_IPV6_GATEWAY_IFNAME:
+ nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
+ break;
}
rib_queue_add (&zebrad, rn);
}
@@ -2744,19 +2741,32 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
switch (si->type)
{
- case STATIC_IPV4_GATEWAY:
- nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
- nh_p.family = AF_INET;
- nh_p.prefixlen = IPV4_MAX_BITLEN;
- nh_p.u.prefix4 = si->gate.ipv4;
- zebra_register_rnh_static_nh(&nh_p, rn);
- break;
- case STATIC_IPV4_IFNAME:
- nexthop_ifname_add (rib, si->gate.ifname);
- break;
- case STATIC_IPV4_BLACKHOLE:
- nexthop_blackhole_add (rib);
- break;
+ case STATIC_IPV4_GATEWAY:
+ nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
+ nh_p.family = AF_INET;
+ nh_p.prefixlen = IPV4_MAX_BITLEN;
+ nh_p.u.prefix4 = si->addr.ipv4;
+ zebra_register_rnh_static_nh(&nh_p, rn);
+ break;
+ case STATIC_IPV4_IFNAME:
+ nexthop_ifname_add (rib, si->ifname);
+ break;
+ case STATIC_IPV4_BLACKHOLE:
+ nexthop_blackhole_add (rib);
+ break;
+ case STATIC_IPV6_GATEWAY:
+ nexthop_ipv6_add (rib, &si->addr.ipv6);
+ nh_p.family = AF_INET6;
+ nh_p.prefixlen = IPV6_MAX_BITLEN;
+ nh_p.u.prefix6 = si->addr.ipv6;
+ zebra_register_rnh_static_nh(&nh_p, rn);
+ break;
+ case STATIC_IPV6_IFNAME:
+ nexthop_ifname_add (rib, si->ifname);
+ break;
+ case STATIC_IPV6_GATEWAY_IFNAME:
+ nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname);
+ break;
}
/* Save the flags of this static routes (reject, blackhole) */
@@ -2768,25 +2778,38 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
}
static int
-static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
+static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
{
if (nexthop->type == NEXTHOP_TYPE_IPV4
&& si->type == STATIC_IPV4_GATEWAY
- && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
+ && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4))
return 1;
if (nexthop->type == NEXTHOP_TYPE_IFNAME
&& si->type == STATIC_IPV4_IFNAME
- && strcmp (nexthop->ifname, si->gate.ifname) == 0)
+ && strcmp (nexthop->ifname, si->ifname) == 0)
return 1;
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
&& si->type == STATIC_IPV4_BLACKHOLE)
return 1;
+ if (nexthop->type == NEXTHOP_TYPE_IPV6
+ && si->type == STATIC_IPV6_GATEWAY
+ && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6))
+ return 1;
+ if (nexthop->type == NEXTHOP_TYPE_IFNAME
+ && si->type == STATIC_IPV6_IFNAME
+ && strcmp (nexthop->ifname, si->ifname) == 0)
+ return 1;
+ if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
+ && si->type == STATIC_IPV6_GATEWAY_IFNAME
+ && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
+ && strcmp (nexthop->ifname, si->ifname) == 0)
+ return 1;
return 0;
}
/* Uninstall static route from RIB. */
static void
-static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
+static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
{
struct route_node *rn;
struct rib *rib;
@@ -2795,7 +2818,7 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
struct prefix nh_p;
/* Lookup table. */
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, si->vrf_id);
+ table = zebra_vrf_table (afi, safi, si->vrf_id);
if (! table)
return;
@@ -2822,7 +2845,7 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
/* Lookup nexthop. */
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
- if (static_ipv4_nexthop_same (nexthop, si))
+ if (static_nexthop_same (nexthop, si))
break;
/* Can't find nexthop. */
@@ -2844,23 +2867,46 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
{
- /* If there are other active nexthops, do an update. */
- if (rib->nexthop_active_num > 1)
- {
- rib_install_kernel (rn, rib, 1);
- redistribute_update (&rn->p, rib, NULL);
- }
- else
+ if (afi == AFI_IP)
+ {
+ /* If there are other active nexthops, do an update. */
+ if (rib->nexthop_active_num > 1)
+ {
+ rib_install_kernel (rn, rib, 1);
+ redistribute_update (&rn->p, rib, NULL);
+ }
+ else
+ {
+ redistribute_delete (&rn->p, rib);
+ rib_uninstall_kernel (rn, rib);
+ }
+ }
+ else
{
redistribute_delete (&rn->p, rib);
rib_uninstall_kernel (rn, rib);
+ /* Are there other active nexthops? */
+ if (rib->nexthop_active_num > 1)
+ {
+ rib_install_kernel (rn, rib, 0);
+ redistribute_update (&rn->p, rib, NULL);
+ }
}
}
- /* Delete the nexthop and dereg from NHT */
- nh_p.family = AF_INET;
- nh_p.prefixlen = IPV4_MAX_BITLEN;
- nh_p.u.prefix4 = nexthop->gate.ipv4;
+ if (afi == AFI_IP)
+ {
+ /* Delete the nexthop and dereg from NHT */
+ nh_p.family = AF_INET;
+ nh_p.prefixlen = IPV4_MAX_BITLEN;
+ nh_p.u.prefix4 = nexthop->gate.ipv4;
+ }
+ else
+ {
+ nh_p.family = AF_INET6;
+ nh_p.prefixlen = IPV6_MAX_BITLEN;
+ nh_p.u.prefix6 = nexthop->gate.ipv6;
+ }
nexthop_delete (rib, nexthop);
zebra_deregister_rnh_static_nh(&nh_p, rn);
nexthop_free (nexthop, rn);
@@ -2876,10 +2922,10 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
{
u_char type = 0;
struct route_node *rn;
- struct static_ipv4 *si;
- struct static_ipv4 *pp;
- struct static_ipv4 *cp;
- struct static_ipv4 *update = NULL;
+ struct static_route *si;
+ struct static_route *pp;
+ struct static_route *cp;
+ struct static_route *update = NULL;
struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
struct route_table *stable = zvrf->stable[AFI_IP][SAFI_UNICAST];
@@ -2901,8 +2947,8 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
for (si = rn->info; si; si = si->next)
{
if (type == si->type
- && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
- && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
+ && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
+ && (! ifname || strcmp (ifname, si->ifname) == 0))
{
if ((distance == si->distance) && (tag == si->tag))
{
@@ -2919,7 +2965,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
static_delete_ipv4 (p, gate, ifname, update->tag, update->distance, vrf_id);
/* Make new static route structure. */
- si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
+ si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
si->type = type;
si->distance = distance;
@@ -2928,9 +2974,9 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
si->vrf_id = vrf_id;
if (gate)
- si->gate.ipv4 = *gate;
+ si->addr.ipv4 = *gate;
if (ifname)
- si->gate.ifname = XSTRDUP (0, ifname);
+ si->ifname = XSTRDUP (0, ifname);
/* Add new static route information to the tree with sort by
distance value and gateway address. */
@@ -2942,9 +2988,9 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
continue;
if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
{
- if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
+ if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr))
break;
- if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
+ if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr))
continue;
}
}
@@ -2960,7 +3006,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
si->next = cp;
/* Install into rib. */
- static_install_ipv4 (p, si);
+ static_install_route (AFI_IP, SAFI_UNICAST, p, si);
return 1;
}
@@ -2972,7 +3018,7 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
{
u_char type = 0;
struct route_node *rn;
- struct static_ipv4 *si;
+ struct static_route *si;
struct route_table *stable;
/* Lookup table. */
@@ -2996,8 +3042,8 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
/* Find same static route is the tree */
for (si = rn->info; si; si = si->next)
if (type == si->type
- && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
- && (! ifname || strcmp (ifname, si->gate.ifname) == 0)
+ && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4))
+ && (! ifname || strcmp (ifname, si->ifname) == 0)
&& (! tag || (tag == si->tag)))
break;
@@ -3009,7 +3055,7 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
}
/* Install into rib. */
- static_uninstall_ipv4 (p, si);
+ static_uninstall_route (AFI_IP, SAFI_UNICAST, p, si);
/* Unlink static route from linked list. */
if (si->prev)
@@ -3022,8 +3068,8 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
/* Free static route configuration. */
if (ifname)
- XFREE (0, si->gate.ifname);
- XFREE (MTYPE_STATIC_IPV4, si);
+ XFREE (0, si->ifname);
+ XFREE (MTYPE_STATIC_ROUTE, si);
route_unlock_node (rn);
@@ -3031,7 +3077,6 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
}
-#ifdef HAVE_IPV6
int
rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
struct in6_addr *gate, unsigned int ifindex, int table)
@@ -3442,200 +3487,6 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
return 0;
}
-/* Install static route into rib. */
-static void
-static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
-{
- struct rib *rib;
- struct route_table *table;
- struct route_node *rn;
- struct prefix nh_p;
-
- /* Lookup table. */
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id);
- if (! table)
- return;
-
- /* Lookup existing route */
- rn = route_node_get (table, p);
- RNODE_FOREACH_RIB (rn, rib)
- {
- if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
- continue;
-
- if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
- break;
- }
-
- if (rib)
- {
- /* if tag value changed , update old value in RIB */
- if (rib->tag != si->tag)
- rib->tag = si->tag;
-
- /* Same distance static route is there. Update it with new
- nexthop. */
- route_unlock_node (rn);
-
- switch (si->type)
- {
- case STATIC_IPV6_GATEWAY:
- nexthop_ipv6_add (rib, &si->ipv6);
- nh_p.family = AF_INET6;
- nh_p.prefixlen = IPV6_MAX_BITLEN;
- nh_p.u.prefix6 = si->ipv6;
- zebra_register_rnh_static_nh(&nh_p, rn);
- break;
- case STATIC_IPV6_IFNAME:
- nexthop_ifname_add (rib, si->ifname);
- break;
- case STATIC_IPV6_GATEWAY_IFNAME:
- nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
- break;
- }
- rib_queue_add (&zebrad, rn);
- }
- else
- {
- /* This is new static route. */
- rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
-
- rib->type = ZEBRA_ROUTE_STATIC;
- rib->instance = 0;
- rib->distance = si->distance;
- rib->metric = 0;
- rib->vrf_id = si->vrf_id;
- rib->table = zebrad.rtm_table_default;
- rib->nexthop_num = 0;
- rib->tag = si->tag;
-
- switch (si->type)
- {
- case STATIC_IPV6_GATEWAY:
- nexthop_ipv6_add (rib, &si->ipv6);
- nh_p.family = AF_INET6;
- nh_p.prefixlen = IPV6_MAX_BITLEN;
- nh_p.u.prefix6 = si->ipv6;
- zebra_register_rnh_static_nh(&nh_p, rn);
- break;
- case STATIC_IPV6_IFNAME:
- nexthop_ifname_add (rib, si->ifname);
- break;
- case STATIC_IPV6_GATEWAY_IFNAME:
- nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
- break;
- }
-
- /* Save the flags of this static routes (reject, blackhole) */
- rib->flags = si->flags;
-
- /* Link this rib to the tree. */
- rib_addnode (rn, rib);
- }
-}
-
-static int
-static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
-{
- if (nexthop->type == NEXTHOP_TYPE_IPV6
- && si->type == STATIC_IPV6_GATEWAY
- && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
- return 1;
- if (nexthop->type == NEXTHOP_TYPE_IFNAME
- && si->type == STATIC_IPV6_IFNAME
- && strcmp (nexthop->ifname, si->ifname) == 0)
- return 1;
- if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
- && si->type == STATIC_IPV6_GATEWAY_IFNAME
- && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
- && strcmp (nexthop->ifname, si->ifname) == 0)
- return 1;
- return 0;
-}
-
-static void
-static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
-{
- struct route_table *table;
- struct route_node *rn;
- struct rib *rib;
- struct nexthop *nexthop;
- struct prefix nh_p;
-
- /* Lookup table. */
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id);
- if (! table)
- return;
-
- /* Lookup existing route with type and distance. */
- rn = route_node_lookup (table, (struct prefix *) p);
- if (! rn)
- return;
-
- RNODE_FOREACH_RIB (rn, rib)
- {
- if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
- continue;
-
- if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance &&
- rib->tag == si->tag)
- break;
- }
-
- if (! rib)
- {
- route_unlock_node (rn);
- return;
- }
-
- /* Lookup nexthop. */
- for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
- if (static_ipv6_nexthop_same (nexthop, si))
- break;
-
- /* Can't find nexthop. */
- if (! nexthop)
- {
- route_unlock_node (rn);
- return;
- }
-
- /* Check nexthop. */
- if (rib->nexthop_num == 1)
- {
- rib_delnode (rn, rib);
- }
- else
- {
- /* Mark this nexthop as inactive and reinstall the route. Then, delete
- * the nexthop. There is no need to re-evaluate the route for this
- * scenario.
- */
- UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
- {
- redistribute_delete (&rn->p, rib);
- rib_uninstall_kernel (rn, rib);
- /* Are there other active nexthops? */
- if (rib->nexthop_active_num > 1)
- {
- rib_install_kernel (rn, rib, 0);
- redistribute_update (&rn->p, rib, NULL);
- }
- }
-
- /* Delete the nexthop and dereg from NHT */
- nh_p.family = AF_INET6;
- nh_p.prefixlen = IPV6_MAX_BITLEN;
- nh_p.u.prefix6 = nexthop->gate.ipv6;
- nexthop_delete (rib, nexthop);
- zebra_deregister_rnh_static_nh(&nh_p, rn);
- nexthop_free (nexthop, rn);
- }
- /* Unlock node. */
- route_unlock_node (rn);
-}
-
/* Add static route into static route configuration. */
int
static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
@@ -3643,9 +3494,10 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
u_char distance, vrf_id_t vrf_id)
{
struct route_node *rn;
- struct static_ipv6 *si;
- struct static_ipv6 *pp;
- struct static_ipv6 *cp;
+ struct static_route *si;
+ struct static_route *pp;
+ struct static_route *cp;
+ struct static_route *update = NULL;
struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
@@ -3666,19 +3518,26 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
/* Do nothing if there is a same static route. */
for (si = rn->info; si; si = si->next)
{
- if (distance == si->distance
- && type == si->type
- && tag == si->tag
- && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
+ if (type == si->type
+ && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
&& (! ifname || strcmp (ifname, si->ifname) == 0))
{
- route_unlock_node (rn);
- return 0;
+ if ((distance == si->distance) && (tag == si->tag))
+ {
+ route_unlock_node (rn);
+ return 0;
+ }
+ else
+ update = si;
}
}
+ /* Distance or tag changed. */
+ if (update)
+ static_delete_ipv6 (p, type, gate, ifname, update->tag, update->distance, vrf_id);
+
/* Make new static route structure. */
- si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
+ si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
si->type = type;
si->distance = distance;
@@ -3689,13 +3548,13 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
switch (type)
{
case STATIC_IPV6_GATEWAY:
- si->ipv6 = *gate;
+ si->addr.ipv6 = *gate;
break;
case STATIC_IPV6_IFNAME:
si->ifname = XSTRDUP (0, ifname);
break;
case STATIC_IPV6_GATEWAY_IFNAME:
- si->ipv6 = *gate;
+ si->addr.ipv6 = *gate;
si->ifname = XSTRDUP (0, ifname);
break;
}
@@ -3721,7 +3580,7 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
si->next = cp;
/* Install into rib. */
- static_install_ipv6 (p, si);
+ static_install_route (AFI_IP6, SAFI_UNICAST, p, si);
return 1;
}
@@ -3733,7 +3592,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
vrf_id_t vrf_id)
{
struct route_node *rn;
- struct static_ipv6 *si;
+ struct static_route *si;
struct route_table *stable;
/* Lookup table. */
@@ -3750,7 +3609,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
for (si = rn->info; si; si = si->next)
if (distance == si->distance
&& type == si->type
- && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
+ && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6))
&& (! ifname || strcmp (ifname, si->ifname) == 0)
&& (! tag || (tag == si->tag)))
break;
@@ -3763,7 +3622,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
}
/* Install into rib. */
- static_uninstall_ipv6 (p, si);
+ static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si);
/* Unlink static route from linked list. */
if (si->prev)
@@ -3776,11 +3635,10 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
/* Free static route configuration. */
if (ifname)
XFREE (0, si->ifname);
- XFREE (MTYPE_STATIC_IPV6, si);
+ XFREE (MTYPE_STATIC_ROUTE, si);
return 1;
}
-#endif /* HAVE_IPV6 */
/* RIB update function. */
void
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 4341152e09..57c0e8265e 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -3006,7 +3006,7 @@ static int
static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
{
struct route_node *rn;
- struct static_ipv4 *si;
+ struct static_route *si;
struct route_table *stable;
struct zebra_vrf *zvrf;
vrf_iter_t iter;
@@ -3029,10 +3029,10 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
switch (si->type)
{
case STATIC_IPV4_GATEWAY:
- vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
+ vty_out (vty, " %s", inet_ntoa (si->addr.ipv4));
break;
case STATIC_IPV4_IFNAME:
- vty_out (vty, " %s", si->gate.ifname);
+ vty_out (vty, " %s", si->ifname);
break;
case STATIC_IPV4_BLACKHOLE:
vty_out (vty, " Null0");
@@ -5128,7 +5128,7 @@ static int
static_config_ipv6 (struct vty *vty)
{
struct route_node *rn;
- struct static_ipv6 *si;
+ struct static_route *si;
int write;
char buf[BUFSIZ];
struct route_table *stable;
@@ -5148,21 +5148,19 @@ static_config_ipv6 (struct vty *vty)
{
vty_out (vty, "ipv6 route %s", prefix2str (&rn->p, buf, sizeof buf));
- switch (si->type)
- {
- case STATIC_IPV6_GATEWAY:
- vty_out (vty, " %s",
- inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
- break;
- case STATIC_IPV6_IFNAME:
- vty_out (vty, " %s", si->ifname);
- break;
- case STATIC_IPV6_GATEWAY_IFNAME:
- vty_out (vty, " %s %s",
- inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ),
- si->ifname);
- break;
- }
+ switch (si->type)
+ {
+ case STATIC_IPV6_GATEWAY:
+ vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ));
+ break;
+ case STATIC_IPV6_IFNAME:
+ vty_out (vty, " %s", si->ifname);
+ break;
+ case STATIC_IPV6_GATEWAY_IFNAME:
+ vty_out (vty, " %s %s",
+ inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ), si->ifname);
+ break;
+ }
if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
vty_out (vty, " %s", "reject");