File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / babeld / source.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:22:28 2012 UTC (12 years, 5 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, v0_99_21, HEAD
quagga

    1: /*  
    2:  *  This file is free software: you may copy, redistribute and/or modify it  
    3:  *  under the terms of the GNU General Public License as published by the  
    4:  *  Free Software Foundation, either version 2 of the License, or (at your  
    5:  *  option) any later version.  
    6:  *  
    7:  *  This file is distributed in the hope that it will be useful, but  
    8:  *  WITHOUT ANY WARRANTY; without even the implied warranty of  
    9:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  
   10:  *  General Public License for more details.  
   11:  *  
   12:  *  You should have received a copy of the GNU General Public License  
   13:  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.  
   14:  *  
   15:  * This file incorporates work covered by the following copyright and  
   16:  * permission notice:  
   17:  *  
   18: Copyright (c) 2007, 2008 by Juliusz Chroboczek
   19: 
   20: Permission is hereby granted, free of charge, to any person obtaining a copy
   21: of this software and associated documentation files (the "Software"), to deal
   22: in the Software without restriction, including without limitation the rights
   23: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   24: copies of the Software, and to permit persons to whom the Software is
   25: furnished to do so, subject to the following conditions:
   26: 
   27: The above copyright notice and this permission notice shall be included in
   28: all copies or substantial portions of the Software.
   29: 
   30: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   31: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   32: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
   33: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   34: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   35: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   36: THE SOFTWARE.
   37: */
   38: 
   39: #include <stdlib.h>
   40: #include <stdio.h>
   41: #include <string.h>
   42: #include <sys/time.h>
   43: 
   44: #include "babel_main.h"
   45: #include "babeld.h"
   46: #include "util.h"
   47: #include "source.h"
   48: #include "babel_interface.h"
   49: #include "route.h"
   50: 
   51: struct source *srcs = NULL;
   52: 
   53: struct source*
   54: find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
   55:             int create, unsigned short seqno)
   56: {
   57:     struct source *src;
   58: 
   59:     for(src = srcs; src; src = src->next) {
   60:         /* This should really be a hash table.  For now, check the
   61:            last byte first. */
   62:         if(src->id[7] != id[7])
   63:             continue;
   64:         if(memcmp(src->id, id, 8) != 0)
   65:             continue;
   66:         if(src->plen != plen)
   67:             continue;
   68:         if(memcmp(src->prefix, p, 16) == 0)
   69:             return src;
   70:     }
   71: 
   72:     if(!create)
   73:         return NULL;
   74: 
   75:     src = malloc(sizeof(struct source));
   76:     if(src == NULL) {
   77:         zlog_err("malloc(source): %s", safe_strerror(errno));
   78:         return NULL;
   79:     }
   80: 
   81:     memcpy(src->id, id, 8);
   82:     memcpy(src->prefix, p, 16);
   83:     src->plen = plen;
   84:     src->seqno = seqno;
   85:     src->metric = INFINITY;
   86:     src->time = babel_now.tv_sec;
   87:     src->route_count = 0;
   88:     src->next = srcs;
   89:     srcs = src;
   90:     return src;
   91: }
   92: 
   93: struct source *
   94: retain_source(struct source *src)
   95: {
   96:     assert(src->route_count < 0xffff);
   97:     src->route_count++;
   98:     return src;
   99: }
  100: 
  101: void
  102: release_source(struct source *src)
  103: {
  104:     assert(src->route_count > 0);
  105:     src->route_count--;
  106: }
  107: 
  108: int
  109: flush_source(struct source *src)
  110: {
  111:     if(src->route_count > 0)
  112:         /* The source is in use by a route. */
  113:         return 0;
  114: 
  115:     if(srcs == src) {
  116:         srcs = src->next;
  117:     } else {
  118:         struct source *previous = srcs;
  119:         while(previous->next != src)
  120:             previous = previous->next;
  121:         previous->next = src->next;
  122:     }
  123: 
  124:     free(src);
  125:     return 1;
  126: }
  127: 
  128: void
  129: update_source(struct source *src,
  130:               unsigned short seqno, unsigned short metric)
  131: {
  132:     if(metric >= INFINITY)
  133:         return;
  134: 
  135:     /* If a source is expired, pretend that it doesn't exist and update
  136:        it unconditionally.  This makes ensures that old data will
  137:        eventually be overridden, and prevents us from getting stuck if
  138:        a router loses its sequence number. */
  139:     if(src->time < babel_now.tv_sec - SOURCE_GC_TIME ||
  140:        seqno_compare(src->seqno, seqno) < 0 ||
  141:        (src->seqno == seqno && src->metric > metric)) {
  142:         src->seqno = seqno;
  143:         src->metric = metric;
  144:     }
  145:     src->time = babel_now.tv_sec;
  146: }
  147: 
  148: void
  149: expire_sources()
  150: {
  151:     struct source *src;
  152: 
  153:     src = srcs;
  154:     while(src) {
  155:         if(src->time > babel_now.tv_sec)
  156:             /* clock stepped */
  157:             src->time = babel_now.tv_sec;
  158:         if(src->time < babel_now.tv_sec - SOURCE_GC_TIME) {
  159:             struct source *old = src;
  160:             src = src->next;
  161:             flush_source(old);
  162:             continue;
  163:         }
  164:         src = src->next;
  165:     }
  166: }
  167: 
  168: void
  169: check_sources_released(void)
  170: {
  171:     struct source *src;
  172: 
  173:     for(src = srcs; src; src = src->next) {
  174:         if(src->route_count != 0)
  175:             fprintf(stderr, "Warning: source %s %s has refcount %d.\n",
  176:                     format_eui64(src->id),
  177:                     format_prefix(src->prefix, src->plen),
  178:                     (int)src->route_count);
  179:     }
  180: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>