summaryrefslogtreecommitdiff
path: root/zebra/zebra_static.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_static.c')
-rw-r--r--zebra/zebra_static.c187
1 files changed, 84 insertions, 103 deletions
diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c
index 5894a8955b..05336ca6b2 100644
--- a/zebra/zebra_static.c
+++ b/zebra/zebra_static.c
@@ -15,16 +15,17 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Quagga; see the file COPYING. If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include <lib/nexthop.h>
#include <lib/memory.h>
+#include <lib/srcdest_table.h>
+#include "vty.h"
#include "zebra/debug.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
@@ -36,9 +37,10 @@
/* Install static route into rib. */
void
-static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
+static_install_route (afi_t afi, safi_t safi, struct prefix *p,
+ struct prefix_ipv6 *src_p, struct static_route *si)
{
- struct rib *rib;
+ struct route_entry *re;
struct route_node *rn;
struct route_table *table;
struct prefix nh_p;
@@ -49,22 +51,24 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
if (! table)
return;
+ memset (&nh_p, 0, sizeof (nh_p));
+
/* Lookup existing route */
- rn = route_node_get (table, p);
- RNODE_FOREACH_RIB (rn, rib)
+ rn = srcdest_rnode_get (table, p, src_p);
+ RNODE_FOREACH_RE (rn, re)
{
- if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
+ if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED))
continue;
- if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
+ if (re->type == ZEBRA_ROUTE_STATIC && re->distance == si->distance)
break;
}
- if (rib)
+ if (re)
{
/* if tag value changed , update old value in RIB */
- if (rib->tag != si->tag)
- rib->tag = si->tag;
+ if (re->tag != si->tag)
+ re->tag = si->tag;
/* Same distance static route is there. Update it with new
nexthop. */
@@ -72,27 +76,27 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
switch (si->type)
{
case STATIC_IPV4_GATEWAY:
- nexthop = rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
+ nexthop = route_entry_nexthop_ipv4_add (re, &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(si->vrf_id, &nh_p, rn);
break;
case STATIC_IFINDEX:
- nexthop = rib_nexthop_ifindex_add (rib, si->ifindex);
+ nexthop = route_entry_nexthop_ifindex_add (re, si->ifindex);
break;
case STATIC_BLACKHOLE:
- nexthop = rib_nexthop_blackhole_add (rib);
+ nexthop = route_entry_nexthop_blackhole_add (re);
break;
case STATIC_IPV6_GATEWAY:
- nexthop = rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
+ nexthop = route_entry_nexthop_ipv6_add (re, &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(si->vrf_id, &nh_p, rn);
break;
case STATIC_IPV6_GATEWAY_IFINDEX:
- nexthop = rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6,
+ nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &si->addr.ipv6,
si->ifindex);
break;
}
@@ -107,8 +111,8 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
if (IS_ZEBRA_DEBUG_RIB)
{
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)",
- si->vrf_id, buf, p->prefixlen, rn, rib, rib->type);
+ zlog_debug ("%u:%s/%d: Modifying route rn %p, re %p (type %d)",
+ si->vrf_id, buf, p->prefixlen, rn, re, re->type);
}
}
/* Schedule route for processing or invoke NHT, as appropriate. */
@@ -121,42 +125,42 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
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->mtu = 0;
- rib->vrf_id = si->vrf_id;
- rib->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default;
- rib->nexthop_num = 0;
- rib->tag = si->tag;
+ re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
+
+ re->type = ZEBRA_ROUTE_STATIC;
+ re->instance = 0;
+ re->distance = si->distance;
+ re->metric = 0;
+ re->mtu = 0;
+ re->vrf_id = si->vrf_id;
+ re->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default;
+ re->nexthop_num = 0;
+ re->tag = si->tag;
switch (si->type)
{
case STATIC_IPV4_GATEWAY:
- nexthop = rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL);
+ nexthop = route_entry_nexthop_ipv4_add (re, &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(si->vrf_id, &nh_p, rn);
break;
case STATIC_IFINDEX:
- nexthop = rib_nexthop_ifindex_add (rib, si->ifindex);
+ nexthop = route_entry_nexthop_ifindex_add (re, si->ifindex);
break;
case STATIC_BLACKHOLE:
- nexthop = rib_nexthop_blackhole_add (rib);
+ nexthop = route_entry_nexthop_blackhole_add (re);
break;
case STATIC_IPV6_GATEWAY:
- nexthop = rib_nexthop_ipv6_add (rib, &si->addr.ipv6);
+ nexthop = route_entry_nexthop_ipv6_add (re, &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(si->vrf_id, &nh_p, rn);
break;
case STATIC_IPV6_GATEWAY_IFINDEX:
- nexthop = rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6,
+ nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &si->addr.ipv6,
si->ifindex);
break;
}
@@ -166,7 +170,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
&si->snh_label.label[0]);
/* Save the flags of this static routes (reject, blackhole) */
- rib->flags = si->flags;
+ re->flags = si->flags;
if (IS_ZEBRA_DEBUG_RIB)
{
@@ -174,50 +178,27 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
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)",
- si->vrf_id, buf, p->prefixlen, rn, rib, rib->type);
+ zlog_debug ("%u:%s/%d: Inserting route rn %p, re %p (type %d)",
+ si->vrf_id, buf, p->prefixlen, rn, re, re->type);
}
}
- /* Link this rib to the tree. Schedule for processing or invoke NHT,
+ /* Link this re to the tree. Schedule for processing or invoke NHT,
* as appropriate.
*/
if (si->type == STATIC_IPV4_GATEWAY ||
si->type == STATIC_IPV6_GATEWAY)
{
- rib_addnode (rn, rib, 0);
+ rib_addnode (rn, re, 0);
zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p);
}
else
- rib_addnode (rn, rib, 1);
+ rib_addnode (rn, re, 1);
}
}
static int
-static_nexthop_label_same (struct nexthop *nexthop,
- struct static_nh_label *snh_label)
-{
- int i;
-
- if ((snh_label->num_labels == 0 && nexthop->nh_label) ||
- (snh_label->num_labels != 0 && !nexthop->nh_label))
- return 0;
-
- if (snh_label->num_labels != 0)
- if (snh_label->num_labels != nexthop->nh_label->num_labels)
- return 0;
-
- for (i = 0; i < snh_label->num_labels; i++)
- if (snh_label->label[i] != nexthop->nh_label->label[i])
- return 0;
-
- return 1;
-}
-
-static int
static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
{
- int gw_match = 0;
-
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
&& si->type == STATIC_BLACKHOLE)
return 1;
@@ -225,34 +206,31 @@ 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->addr.ipv4))
- gw_match = 1;
+ return 1;
else if (nexthop->type == NEXTHOP_TYPE_IFINDEX
&& si->type == STATIC_IFINDEX
&& nexthop->ifindex == si->ifindex)
- gw_match = 1;
+ return 1;
else if (nexthop->type == NEXTHOP_TYPE_IPV6
&& si->type == STATIC_IPV6_GATEWAY
&& IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6))
- gw_match = 1;
+ return 1;
else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
&& si->type == STATIC_IPV6_GATEWAY_IFINDEX
&& IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)
&& nexthop->ifindex == si->ifindex)
- gw_match = 1;
-
- if (!gw_match)
- return 0;
+ return 1;
- /* Check match on label(s), if any */
- return static_nexthop_label_same (nexthop, &si->snh_label);
+ return 0;
}
/* Uninstall static route from RIB. */
void
-static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si)
+static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p,
+ struct prefix_ipv6 *src_p, struct static_route *si)
{
struct route_node *rn;
- struct rib *rib;
+ struct route_entry *re;
struct nexthop *nexthop;
struct route_table *table;
struct prefix nh_p;
@@ -263,28 +241,28 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
return;
/* Lookup existing route with type and distance. */
- rn = route_node_lookup (table, p);
+ rn = srcdest_rnode_lookup (table, p, src_p);
if (! rn)
return;
- RNODE_FOREACH_RIB (rn, rib)
+ RNODE_FOREACH_RE (rn, re)
{
- if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
+ if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED))
continue;
- if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance &&
- rib->tag == si->tag)
+ if (re->type == ZEBRA_ROUTE_STATIC && re->distance == si->distance &&
+ re->tag == si->tag)
break;
}
- if (! rib)
+ if (! re)
{
route_unlock_node (rn);
return;
}
/* Lookup nexthop. */
- for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
+ for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
if (static_nexthop_same (nexthop, si))
break;
@@ -296,8 +274,8 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
}
/* Check nexthop. */
- if (rib->nexthop_num == 1)
- rib_delnode (rn, rib);
+ if (re->nexthop_num == 1)
+ rib_delnode (rn, re);
else
{
/* Mark this nexthop as inactive and reinstall the route. Then, delete
@@ -310,31 +288,31 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
if (IS_ZEBRA_DEBUG_RIB)
{
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)",
- si->vrf_id, buf, p->prefixlen, rn, rib, rib->type);
+ zlog_debug ("%u:%s/%d: Modifying route rn %p, re %p (type %d)",
+ si->vrf_id, buf, p->prefixlen, rn, re, re->type);
}
}
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)
+ if (re->nexthop_active_num > 1)
{
/* Update route in kernel if it's in fib */
- if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
- rib_install_kernel (rn, rib, rib);
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
+ rib_install_kernel (rn, re, re);
/* Update redistribution if it's selected */
- if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
- redistribute_update (&rn->p, rib, NULL);
+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
+ redistribute_update (p, (struct prefix*)src_p, re, NULL);
}
else
{
/* Remove from redistribute if selected route becomes inactive */
- if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
- redistribute_delete (&rn->p, rib);
+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
+ redistribute_delete (p, (struct prefix*)src_p, re);
/* Remove from kernel if fib route becomes inactive */
- if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
- rib_uninstall_kernel (rn, rib);
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB))
+ rib_uninstall_kernel (rn, re);
}
}
@@ -351,7 +329,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = nexthop->gate.ipv6;
}
- rib_nexthop_delete (rib, nexthop);
+ route_entry_nexthop_delete (re, nexthop);
zebra_deregister_rnh_static_nh(si->vrf_id, &nh_p, rn);
nexthop_free (nexthop);
}
@@ -361,6 +339,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
int
static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
+ struct prefix_ipv6 *src_p,
union g_addr *gate, ifindex_t ifindex,
const char *ifname, u_char flags, route_tag_t tag,
u_char distance, struct zebra_vrf *zvrf,
@@ -388,7 +367,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
return -1;
/* Lookup static route prefix. */
- rn = route_node_get (stable, p);
+ rn = srcdest_rnode_get (stable, p, src_p);
/* Do nothing if there is a same static route. */
for (si = rn->info; si; si = si->next)
@@ -400,7 +379,8 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
&& (! ifindex || ifindex == si->ifindex))
{
if ((distance == si->distance) && (tag == si->tag) &&
- !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label)))
+ !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label)) &&
+ si->flags == flags)
{
route_unlock_node (rn);
return 0;
@@ -412,7 +392,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
/* Distance or tag or label changed, delete existing first. */
if (update)
- static_delete_route (afi, safi, type, p, gate, ifindex, update->tag,
+ static_delete_route (afi, safi, type, p, src_p, gate, ifindex, update->tag,
update->distance, zvrf, &update->snh_label);
/* Make new static route structure. */
@@ -473,13 +453,14 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
si->next = cp;
/* Install into rib. */
- static_install_route (afi, safi, p, si);
+ static_install_route (afi, safi, p, src_p, si);
return 1;
}
int
static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
+ struct prefix_ipv6 *src_p,
union g_addr *gate, ifindex_t ifindex,
route_tag_t tag, u_char distance, struct zebra_vrf *zvrf,
struct static_nh_label *snh_label)
@@ -494,7 +475,7 @@ static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
return -1;
/* Lookup static route prefix. */
- rn = route_node_lookup (stable, p);
+ rn = srcdest_rnode_lookup (stable, p, src_p);
if (! rn)
return 0;
@@ -518,7 +499,7 @@ static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
}
/* Install into rib. */
- static_uninstall_route (afi, safi, p, si);
+ static_uninstall_route (afi, safi, p, src_p, si);
/* Unlink static route from linked list. */
if (si->prev)