1
1
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
2
2
// vim:set sts=4 ts=8:
4
// Copyright (c) 2001-2007 International Computer Science Institute
4
// Copyright (c) 2001-2008 International Computer Science Institute
6
6
// Permission is hereby granted, free of charge, to any person obtaining a
7
7
// copy of this software and associated documentation files (the "Software")
13
13
// notice is a summary of the XORP LICENSE file; the license in that file is
14
14
// legally binding.
16
#ident "$XORP: xorp/rib/rib.cc,v 1.66 2007/05/23 12:12:46 pavlin Exp $"
16
#ident "$XORP: xorp/rib/rib.cc,v 1.71 2008/01/04 22:03:28 pavlin Exp $"
18
18
#include "rib_module.h"
160
160
template <typename A>
162
162
RIB<A>::find_vif(const A& addr)
164
map<string, Vif>::iterator iter;
164
map<string, RibVif*>::iterator iter;
166
166
for (iter = _vifs.begin(); iter != _vifs.end(); ++iter) {
167
Vif& vif = iter->second;
168
if (! vif.is_underlying_vif_up())
167
RibVif* vif = iter->second;
168
if (! vif->is_underlying_vif_up())
169
169
continue; // XXX: ignore vifs that are not up
170
if (vif.is_my_addr(addr))
172
if (vif.is_p2p() && vif.is_same_p2p(addr))
170
if (vif->is_my_addr(addr))
172
if (vif->is_p2p() && vif->is_same_p2p(addr))
281
281
delete _tables.front();
282
282
_tables.pop_front();
284
while (_vifs.empty() == false) {
285
delete _vifs.begin()->second;
286
_vifs.erase(_vifs.begin());
288
while (_deleted_vifs.empty() == false) {
289
delete _deleted_vifs.begin()->second;
290
_deleted_vifs.erase(_deleted_vifs.begin());
286
294
template <typename A>
469
477
template <typename A>
471
RIB<A>::delete_connected_route(const Vif& vif, const IPNet<A>& net,
479
RIB<A>::delete_connected_route(const RibVif& vif, const IPNet<A>& net,
472
480
const A& peer_addr)
474
482
delete_route("connected", net);
485
493
RIB<A>::new_vif(const string& vifname, const Vif& vif)
495
map<string, RibVif*>::iterator vi;
496
RibVif* new_rib_vif = NULL;
487
498
debug_msg("RIB::new_vif: %s\n", vifname.c_str());
488
499
if (_vifs.find(vifname) != _vifs.end())
489
500
return XORP_ERROR;
491
// Can't use _vifs[vifname] = vif because no Vif() constructor
492
map<string, Vif>::value_type v(vifname, vif);
493
_vifs.insert(_vifs.end(), v);
495
// We need to add the routes from the VIF to the connected table
496
map<string, Vif>::iterator iter = _vifs.find(vifname);
497
XLOG_ASSERT(iter != _vifs.end());
498
Vif* new_vif = &(iter->second);
499
XLOG_ASSERT(new_vif != NULL);
501
if (vif.is_underlying_vif_up()) {
503
// If the vif is pending deletion, then reuse it instead
505
vi = _deleted_vifs.find(vifname);
506
if (vi != _deleted_vifs.end()) {
507
// Reuse previously deleted vif
508
new_rib_vif = vi->second;
509
new_rib_vif->set_deleted(false);
510
_deleted_vifs.erase(vi);
511
new_rib_vif->copy_in(vif);
514
new_rib_vif = new RibVif(this, vif);
516
XLOG_ASSERT(new_rib_vif != NULL);
517
_vifs[vifname] = new_rib_vif;
519
if (new_rib_vif->is_underlying_vif_up()) {
503
521
// Add the directly connected routes associated with this vif
505
523
list<VifAddr>::const_iterator ai;
506
for (ai = new_vif->addr_list().begin();
507
ai != new_vif->addr_list().end();
524
for (ai = new_rib_vif->addr_list().begin();
525
ai != new_rib_vif->addr_list().end();
509
527
if (ai->addr().af() != A::af())
514
532
ai->subnet_addr().get(subnet_addr);
515
533
ai->addr().get(addr);
516
534
ai->peer_addr().get(peer_addr);
517
add_connected_route(*new_vif, subnet_addr, addr, peer_addr);
535
add_connected_route(*new_rib_vif, subnet_addr, addr, peer_addr);
526
544
RIB<A>::delete_vif(const string& vifname)
528
546
debug_msg("RIB::delete_vif: %s\n", vifname.c_str());
529
map<string, Vif>::iterator vi = _vifs.find(vifname);
547
map<string, RibVif*>::iterator vi = _vifs.find(vifname);
530
548
if (vi == _vifs.end()) {
531
549
return XORP_ERROR;
533
Vif& vif = vi->second;
551
RibVif* rib_vif = vi->second;
535
if (vif.is_underlying_vif_up()) {
553
if (rib_vif->is_underlying_vif_up()) {
537
555
// Delete the directly connected routes associated with this vif
539
557
list<VifAddr>::const_iterator ai;
540
for (ai = vif.addr_list().begin(); ai != vif.addr_list().end(); ++ai) {
558
for (ai = rib_vif->addr_list().begin();
559
ai != rib_vif->addr_list().end();
541
561
if (ai->addr().af() != A::af())
546
566
ai->subnet_addr().get(subnet_addr);
547
567
ai->peer_addr().get(peer_addr);
548
delete_connected_route(vif, subnet_addr, peer_addr);
568
delete_connected_route(*rib_vif, subnet_addr, peer_addr);
575
// If the vif is still used by some routes, then add it to the
576
// container with vifs pending deletion.
577
// Otherwise just delete it.
579
if (rib_vif->usage_counter() > 0) {
580
XLOG_ASSERT(_deleted_vifs.find(vifname) == _deleted_vifs.end());
581
_deleted_vifs[vifname] = rib_vif;
582
rib_vif->set_deleted(true);
556
590
template <typename A>
592
RIB<A>::destroy_deleted_vif(RibVif* rib_vif)
594
map<string, RibVif*>::iterator vi = _deleted_vifs.find(rib_vif->name());
596
XLOG_ASSERT(vi != _deleted_vifs.end());
597
XLOG_ASSERT(vi->second == rib_vif);
599
_deleted_vifs.erase(vi);
603
template <typename A>
558
605
RIB<A>::set_vif_flags(const string& vifname,
566
map<string, Vif>::iterator vi = _vifs.find(vifname);
613
map<string, RibVif*>::iterator vi = _vifs.find(vifname);
567
614
if (vi == _vifs.end()) {
568
615
XLOG_ERROR("Attempting to set flags to non-existant Vif \"%s\"",
569
616
vifname.c_str());
570
617
return XORP_ERROR;
572
Vif& vif = vi->second;
574
bool old_is_up = vif.is_underlying_vif_up();
577
vif.set_loopback(is_loopback);
578
vif.set_multicast_capable(is_multicast);
579
vif.set_broadcast_capable(is_broadcast);
580
vif.set_underlying_vif_up(is_up);
619
RibVif* vif = vi->second;
621
bool old_is_up = vif->is_underlying_vif_up();
623
vif->set_p2p(is_p2p);
624
vif->set_loopback(is_loopback);
625
vif->set_multicast_capable(is_multicast);
626
vif->set_broadcast_capable(is_broadcast);
627
vif->set_underlying_vif_up(is_up);
583
630
if (old_is_up == is_up)
590
637
// Add all connected routes
592
for (ai = vif.addr_list().begin(); ai != vif.addr_list().end(); ++ai) {
639
for (ai = vif->addr_list().begin();
640
ai != vif->addr_list().end();
593
642
if (ai->addr().af() != A::af())
598
647
ai->subnet_addr().get(subnet_addr);
599
648
ai->addr().get(addr);
600
649
ai->peer_addr().get(peer_addr);
601
add_connected_route(vif, subnet_addr, addr, peer_addr);
650
add_connected_route(*vif, subnet_addr, addr, peer_addr);
608
657
// Delete all connected routes
610
for (ai = vif.addr_list().begin(); ai != vif.addr_list().end(); ++ai) {
659
for (ai = vif->addr_list().begin();
660
ai != vif->addr_list().end();
611
662
if (ai->addr().af() != A::af())
616
667
ai->subnet_addr().get(subnet_addr);
617
668
ai->peer_addr().get(peer_addr);
618
delete_connected_route(vif, subnet_addr, peer_addr);
669
delete_connected_route(*vif, subnet_addr, peer_addr);
630
681
const A& broadcast_addr,
631
682
const A& peer_addr)
633
map<string, Vif>::iterator vi = _vifs.find(vifname);
684
map<string, RibVif*>::iterator vi = _vifs.find(vifname);
634
685
if (vi == _vifs.end()) {
635
686
XLOG_ERROR("Attempting to add address to non-existant Vif \"%s\"",
636
687
vifname.c_str());
637
688
return XORP_ERROR;
639
Vif& vif = vi->second;
641
vif.add_address(VifAddr(addr, subnet, broadcast_addr, peer_addr));
643
if (vif.is_underlying_vif_up())
644
add_connected_route(vif, subnet, addr, peer_addr);
690
RibVif* vif = vi->second;
692
vif->add_address(VifAddr(addr, subnet, broadcast_addr, peer_addr));
694
if (vif->is_underlying_vif_up())
695
add_connected_route(*vif, subnet, addr, peer_addr);
651
702
RIB<A>::delete_vif_address(const string& vifname,
654
map<string, Vif>::iterator vi = _vifs.find(vifname);
705
map<string, RibVif*>::iterator vi = _vifs.find(vifname);
655
706
if (vi == _vifs.end()) {
656
707
XLOG_ERROR("Attempting to delete address from non-existant Vif \"%s\"",
657
708
vifname.c_str());
658
709
return XORP_ERROR;
660
Vif& vif = vi->second;
711
RibVif* vif = vi->second;
662
713
list<VifAddr>::const_iterator ai;
663
for (ai = vif.addr_list().begin(); ai != vif.addr_list().end(); ++ai) {
714
for (ai = vif->addr_list().begin(); ai != vif->addr_list().end(); ++ai) {
664
715
const IPvX& ipvx = ai->addr();
665
716
if (ipvx.af() != A::af())
672
723
ai->subnet_addr().get(subnet_addr);
673
724
ai->peer_addr().get(peer_addr);
675
vif.delete_address(ipvx);
726
vif->delete_address(ipvx);
677
if (vif.is_underlying_vif_up())
678
delete_connected_route(vif, subnet_addr, peer_addr);
728
if (vif->is_underlying_vif_up())
729
delete_connected_route(*vif, subnet_addr, peer_addr);
733
784
// Add a route with explicitly specified network interface
735
map<string, Vif>::iterator iter = _vifs.find(vifname);
786
map<string, RibVif*>::iterator iter = _vifs.find(vifname);
736
787
if (iter == _vifs.end()) {
737
788
XLOG_ERROR("Attempting to add route to table \"%s\" "
738
789
"(prefix %s next-hop %s ifname %s vifname %s): "
742
793
ifname.c_str(), vifname.c_str());
743
794
return XORP_ERROR;
745
Vif* vif = &iter->second;
796
RibVif* vif = iter->second;
746
797
IPNextHop<A>* nexthop = find_or_create_peer_nexthop(nexthop_addr);
747
798
ot->add_route(IPRouteEntry<A>(net, vif, nexthop, *protocol,
748
799
metric, policytags));
807
858
XLOG_ASSERT(nexthop->addr() == nexthop_addr);
810
// Only accept the least significant 16 bits of metric.
812
if (metric > 0xffff) {
813
XLOG_WARNING("Protocol metric value %u is greater than 0xffff from "
814
"table \"%s\"", XORP_UINT_CAST(metric),
822
ot->add_route(IPRouteEntry<A>(net, vif, nexthop,
823
*protocol, metric, policytags));
863
ot->add_route(IPRouteEntry<A>(net, vif, nexthop, *protocol, metric,
913
// 3. Check for discard (blackhole) routes.
954
// 3a. Check for discard (blackhole) routes.
914
955
// XXX: re->vif() must be non-NULL and valid. Revisit this in future.
915
956
DiscardNextHop* dnh = dynamic_cast<DiscardNextHop*>(re->nexthop());
916
957
if (matchtype == RibVerifyType(DISCARD)) {
918
debug_msg("Next hop is not a DiscardNextHop");
921
debug_msg("****DISCARD ROUTE SUCCESSFULLY VERIFIED****\n");
959
debug_msg("Next hop is not a DiscardNextHop");
962
debug_msg("****DISCARD ROUTE SUCCESSFULLY VERIFIED****\n");
966
// 3b. Check for unreachable routes.
967
// XXX: re->vif() must be non-NULL and valid. Revisit this in future.
968
UnreachableNextHop* unh = dynamic_cast<UnreachableNextHop*>(re->nexthop());
969
if (matchtype == RibVerifyType(UNREACHABLE)) {
971
debug_msg("Next hop is not an UnreachableNextHop");
974
debug_msg("****UNREACHABLE ROUTE SUCCESSFULLY VERIFIED****\n");
977
1030
DiscardNextHop* discard_nexthop =
978
1031
dynamic_cast<DiscardNextHop* >(re->nexthop());
979
// Case 2: Discard route. Return the loopback address.
1032
// Case 2a: Discard route. Return the loopback address.
980
1033
if (discard_nexthop != NULL)
981
1034
return A::LOOPBACK();
1036
UnreachableNextHop* unreachable_nexthop =
1037
dynamic_cast<UnreachableNextHop* >(re->nexthop());
1038
// Case 2b: Unreachable route. Return the loopback address.
1039
if (unreachable_nexthop != NULL)
1040
return A::LOOPBACK();
983
1042
IPNextHop<A>* ip_nexthop = dynamic_cast<IPNextHop<A>* >(re->nexthop());
984
1043
// Case 3: IP protocol route. Return the nexthop address.
985
1044
if (ip_nexthop != NULL)