1/* 2 * RIPng routes function. 3 * Copyright (C) 1998 Kunihiro Ishiguro 4 * 5 * This file is part of GNU Zebra. 6 * 7 * GNU Zebra is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2, or (at your option) any 10 * later version. 11 * 12 * GNU Zebra is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with GNU Zebra; see the file COPYING. If not, write to the Free 19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 * 02111-1307, USA. 21 */ 22 23#include <zebra.h> 24 25#include "prefix.h" 26#include "table.h" 27#include "memory.h" 28#include "if.h" 29#include "vty.h" 30 31#include "ripngd/ripngd.h" 32#include "ripngd/ripng_route.h" 33 34static struct ripng_aggregate * 35ripng_aggregate_new () 36{ 37 struct ripng_aggregate *new; 38 39 new = XCALLOC (MTYPE_RIPNG_AGGREGATE, sizeof (struct ripng_aggregate)); 40 return new; 41} 42 43static void 44ripng_aggregate_free (struct ripng_aggregate *aggregate) 45{ 46 XFREE (MTYPE_RIPNG_AGGREGATE, aggregate); 47} 48 49/* Aggregate count increment check. */ 50void 51ripng_aggregate_increment (struct route_node *child, struct ripng_info *rinfo) 52{ 53 struct route_node *np; 54 struct ripng_aggregate *aggregate; 55 56 for (np = child; np; np = np->parent) 57 if ((aggregate = np->aggregate) != NULL) 58 { 59 aggregate->count++; 60 rinfo->suppress++; 61 } 62} 63 64/* Aggregate count decrement check. */ 65void 66ripng_aggregate_decrement (struct route_node *child, struct ripng_info *rinfo) 67{ 68 struct route_node *np; 69 struct ripng_aggregate *aggregate; 70 71 for (np = child; np; np = np->parent) 72 if ((aggregate = np->aggregate) != NULL) 73 { 74 aggregate->count--; 75 rinfo->suppress--; 76 } 77} 78 79/* RIPng routes treatment. */ 80int 81ripng_aggregate_add (struct prefix *p) 82{ 83 struct route_node *top; 84 struct route_node *rp; 85 struct ripng_info *rinfo; 86 struct ripng_aggregate *aggregate; 87 struct ripng_aggregate *sub; 88 89 /* Get top node for aggregation. */ 90 top = route_node_get (ripng->table, p); 91 92 /* Allocate new aggregate. */ 93 aggregate = ripng_aggregate_new (); 94 aggregate->metric = 1; 95 96 top->aggregate = aggregate; 97 98 /* Suppress routes match to the aggregate. */ 99 for (rp = route_lock_node (top); rp; rp = route_next_until (rp, top)) 100 { 101 /* Suppress normal route. */ 102 if ((rinfo = rp->info) != NULL) 103 { 104 aggregate->count++; 105 rinfo->suppress++; 106 } 107 /* Suppress aggregate route. This may not need. */ 108 if (rp != top && (sub = rp->aggregate) != NULL) 109 { 110 aggregate->count++; 111 sub->suppress++; 112 } 113 } 114 115 return 0; 116} 117 118/* Delete RIPng static route. */ 119int 120ripng_aggregate_delete (struct prefix *p) 121{ 122 struct route_node *top; 123 struct route_node *rp; 124 struct ripng_info *rinfo; 125 struct ripng_aggregate *aggregate; 126 struct ripng_aggregate *sub; 127 128 /* Get top node for aggregation. */ 129 top = route_node_get (ripng->table, p); 130 131 /* Allocate new aggregate. */ 132 aggregate = top->aggregate; 133 134 /* Suppress routes match to the aggregate. */ 135 for (rp = route_lock_node (top); rp; rp = route_next_until (rp, top)) 136 { 137 /* Suppress normal route. */ 138 if ((rinfo = rp->info) != NULL) 139 { 140 aggregate->count--; 141 rinfo->suppress--; 142 } 143 144 if (rp != top && (sub = rp->aggregate) != NULL) 145 { 146 aggregate->count--; 147 sub->suppress--; 148 } 149 } 150 151 top->aggregate = NULL; 152 ripng_aggregate_free (aggregate); 153 154 route_unlock_node (top); 155 route_unlock_node (top); 156 157 return 0; 158} 159