~ubuntu-branches/ubuntu/jaunty/xorp/jaunty

« back to all changes in this revision

Viewing changes to rib/rib.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jose Calhariz, Javier Fernandez-Sanguino, Jose Calhariz
  • Date: 2008-01-23 01:24:37 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080123012437-7l2u9r0k8e7op8st
Tags: 1.5~cvs.20080128-1
[ Javier Fernandez-Sanguino ]
* Update to latest CVS contents
* Modify debian/rules to prevent autobuilders from building 
  the binary-independent components: (Closes: #441121)
  - Create a new Build-Depends-Indep with all the TeX
  components used to build documentation
  - Since autobuilders call build, which in turns calls build-indep, hack
    the debian rules file so that the documentation is only built if ps2pdf,
    dvips and pslatex are available. 
* Modify the init.d script:
  - restart action: Do not attempt to stop xorp if not running
  - stop function: fix errors in the script
  - add a try-restart action
  - restructure the init.d script, move the restart code to a function
  - review the use of echo calls and exit values
* Use, as examples, the new boot files at rtrmgr/config/

[ Jose Calhariz ]
* Add depends on ncurses-dev, I don't know why xorp use tigetstr
  function from curses.  This way the depends field change less between
  build environments.
* Removed pushd and popd commands from Makefile and replaced with cd
  commands, was a bashism and FTBFS (closes: #453637)
* debian/control converted to utf-8 (closes: #454026) (closes: #453485)
* init.d/xorp now returns 0 if disabled.
* Added Vcs-Browser and Vcs-Svn fields pointing to the repository of the
  package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
2
2
// vim:set sts=4 ts=8:
3
3
 
4
 
// Copyright (c) 2001-2007 International Computer Science Institute
 
4
// Copyright (c) 2001-2008 International Computer Science Institute
5
5
//
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.
15
15
 
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 $"
17
17
 
18
18
#include "rib_module.h"
19
19
 
158
158
}
159
159
 
160
160
template <typename A>
161
 
inline Vif*
 
161
inline RibVif*
162
162
RIB<A>::find_vif(const A& addr)
163
163
{
164
 
    map<string, Vif>::iterator iter;
 
164
    map<string, RibVif*>::iterator iter;
165
165
 
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))
171
 
            return &vif;
172
 
        if (vif.is_p2p() && vif.is_same_p2p(addr))
173
 
            return &vif;
 
170
        if (vif->is_my_addr(addr))
 
171
            return vif;
 
172
        if (vif->is_p2p() && vif->is_same_p2p(addr))
 
173
            return vif;
174
174
    }
175
175
    return NULL;
176
176
}
281
281
        delete _tables.front();
282
282
        _tables.pop_front();
283
283
    }
 
284
    while (_vifs.empty() == false) {
 
285
        delete _vifs.begin()->second;
 
286
        _vifs.erase(_vifs.begin());
 
287
    }
 
288
    while (_deleted_vifs.empty() == false) {
 
289
        delete _deleted_vifs.begin()->second;
 
290
        _deleted_vifs.erase(_deleted_vifs.begin());
 
291
    }
284
292
}
285
293
 
286
294
template <typename A>
447
455
 
448
456
template <typename A>
449
457
int
450
 
RIB<A>::add_connected_route(const Vif& vif,
 
458
RIB<A>::add_connected_route(const RibVif& vif,
451
459
                            const IPNet<A>& net,
452
460
                            const A& nexthop_addr,
453
461
                            const A& peer_addr)
468
476
 
469
477
template <typename A>
470
478
int
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)
473
481
{
474
482
    delete_route("connected", net);
484
492
int
485
493
RIB<A>::new_vif(const string& vifname, const Vif& vif)
486
494
{
 
495
    map<string, RibVif*>::iterator vi;
 
496
    RibVif* new_rib_vif = NULL;
 
497
 
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;
490
501
 
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);
494
 
 
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);
500
 
 
501
 
    if (vif.is_underlying_vif_up()) {
 
502
    //
 
503
    // If the vif is pending deletion, then reuse it instead
 
504
    //
 
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);
 
512
    } else {
 
513
        // Create a new vif
 
514
        new_rib_vif = new RibVif(this, vif);
 
515
    }
 
516
    XLOG_ASSERT(new_rib_vif != NULL);
 
517
    _vifs[vifname] = new_rib_vif;
 
518
 
 
519
    if (new_rib_vif->is_underlying_vif_up()) {
502
520
        //
503
521
        // Add the directly connected routes associated with this vif
504
522
        //
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();
508
526
             ++ai) {
509
527
            if (ai->addr().af() != A::af())
510
528
                continue;
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);
518
536
        }
519
537
    }
520
538
 
526
544
RIB<A>::delete_vif(const string& vifname)
527
545
{
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;
532
550
    }
533
 
    Vif& vif = vi->second;
 
551
    RibVif* rib_vif = vi->second;
534
552
 
535
 
    if (vif.is_underlying_vif_up()) {
 
553
    if (rib_vif->is_underlying_vif_up()) {
536
554
        //
537
555
        // Delete the directly connected routes associated with this vif
538
556
        //
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();
 
560
             ++ai) {
541
561
            if (ai->addr().af() != A::af())
542
562
                continue;
543
563
 
545
565
            A peer_addr;
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);
549
569
        }
550
570
    }
551
571
 
552
572
    _vifs.erase(vi);
 
573
 
 
574
    //
 
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.
 
578
    //
 
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);
 
583
    } else {
 
584
        delete rib_vif;
 
585
    }
 
586
    
553
587
    return XORP_OK;
554
588
}
555
589
 
556
590
template <typename A>
 
591
void
 
592
RIB<A>::destroy_deleted_vif(RibVif* rib_vif)
 
593
{
 
594
    map<string, RibVif*>::iterator vi = _deleted_vifs.find(rib_vif->name());
 
595
 
 
596
    XLOG_ASSERT(vi != _deleted_vifs.end());
 
597
    XLOG_ASSERT(vi->second == rib_vif);
 
598
 
 
599
    _deleted_vifs.erase(vi);
 
600
    delete rib_vif;
 
601
}
 
602
 
 
603
template <typename A>
557
604
int
558
605
RIB<A>::set_vif_flags(const string& vifname,
559
606
                      bool is_p2p,
563
610
                      bool is_up,
564
611
                      uint32_t mtu)
565
612
{
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;
571
618
    }
572
 
    Vif& vif = vi->second;
573
 
 
574
 
    bool old_is_up = vif.is_underlying_vif_up();
575
 
 
576
 
    vif.set_p2p(is_p2p);
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);
581
 
    vif.set_mtu(mtu);
 
619
    RibVif* vif = vi->second;
 
620
 
 
621
    bool old_is_up = vif->is_underlying_vif_up();
 
622
 
 
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);
 
628
    vif->set_mtu(mtu);
582
629
 
583
630
    if (old_is_up == is_up)
584
631
        return XORP_OK;
589
636
        //
590
637
        // Add all connected routes
591
638
        //
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();
 
641
             ++ai) {
593
642
            if (ai->addr().af() != A::af())
594
643
                continue;
595
644
 
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);
602
651
        }
603
652
    }
604
653
 
607
656
        //
608
657
        // Delete all connected routes
609
658
        //
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();
 
661
             ++ai) {
611
662
            if (ai->addr().af() != A::af())
612
663
                continue;
613
664
 
615
666
            A peer_addr;
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);
619
670
        }
620
671
    }
621
672
 
630
681
                        const A&        broadcast_addr,
631
682
                        const A&        peer_addr)
632
683
{
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;
638
689
    }
639
 
    Vif& vif = vi->second;
640
 
 
641
 
    vif.add_address(VifAddr(addr, subnet, broadcast_addr, peer_addr));
642
 
 
643
 
    if (vif.is_underlying_vif_up())
644
 
        add_connected_route(vif, subnet, addr, peer_addr);
 
690
    RibVif* vif = vi->second;
 
691
 
 
692
    vif->add_address(VifAddr(addr, subnet, broadcast_addr, peer_addr));
 
693
 
 
694
    if (vif->is_underlying_vif_up())
 
695
        add_connected_route(*vif, subnet, addr, peer_addr);
645
696
 
646
697
    return XORP_OK;
647
698
}
651
702
RIB<A>::delete_vif_address(const string& vifname,
652
703
                           const A& addr)
653
704
{
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;
659
710
    }
660
 
    Vif& vif = vi->second;
 
711
    RibVif* vif = vi->second;
661
712
    
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())
666
717
            continue;
672
723
        ai->subnet_addr().get(subnet_addr);
673
724
        ai->peer_addr().get(peer_addr);
674
725
 
675
 
        vif.delete_address(ipvx);
 
726
        vif->delete_address(ipvx);
676
727
 
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);
679
730
 
680
731
        return XORP_OK;
681
732
    }
732
783
        //
733
784
        // Add a route with explicitly specified network interface
734
785
        //
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;
744
795
        }
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));
753
804
    //
754
805
    // Find the vif so we can see if the nexthop is directly connected
755
806
    //
756
 
    Vif* vif = NULL;
 
807
    RibVif* vif = NULL;
757
808
    IPNextHop<A>* nexthop = NULL;
758
809
    do {
759
810
        //
807
858
    XLOG_ASSERT(nexthop->addr() == nexthop_addr);
808
859
 
809
860
    //
810
 
    // Only accept the least significant 16 bits of metric.
811
 
    //
812
 
    if (metric > 0xffff) {
813
 
        XLOG_WARNING("Protocol metric value %u is greater than 0xffff from "
814
 
                     "table \"%s\"",  XORP_UINT_CAST(metric),
815
 
                     tablename.c_str());
816
 
        metric &= 0xffff;
817
 
    }
818
 
 
819
 
    //
820
861
    // Add the route
821
862
    //
822
 
    ot->add_route(IPRouteEntry<A>(net, vif, nexthop,
823
 
                                  *protocol, metric, policytags));
 
863
    ot->add_route(IPRouteEntry<A>(net, vif, nexthop, *protocol, metric,
 
864
                                  policytags));
824
865
    flush();
825
866
    return XORP_OK;
826
867
}
910
951
    }
911
952
 
912
953
#ifdef notyet
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)) {
917
 
            if (dnh == NULL) {
918
 
                    debug_msg("Next hop is not a DiscardNextHop");
919
 
                    return XORP_ERROR;
920
 
            } else {
921
 
                debug_msg("****DISCARD ROUTE SUCCESSFULLY VERIFIED****\n");
922
 
                return XORP_OK;
923
 
            }
 
958
        if (dnh == NULL) {
 
959
            debug_msg("Next hop is not a DiscardNextHop");
 
960
            return XORP_ERROR;
 
961
        } else {
 
962
            debug_msg("****DISCARD ROUTE SUCCESSFULLY VERIFIED****\n");
 
963
            return XORP_OK;
 
964
        }
 
965
    }
 
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)) {
 
970
        if (unh == NULL) {
 
971
            debug_msg("Next hop is not an UnreachableNextHop");
 
972
            return XORP_ERROR;
 
973
        } else {
 
974
            debug_msg("****UNREACHABLE ROUTE SUCCESSFULLY VERIFIED****\n");
 
975
            return XORP_OK;
 
976
        }
924
977
    }
925
978
#endif
926
979
 
976
1029
#ifdef notyet
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();
982
1035
 
 
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();
 
1041
 
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)