Annotation of embedaddon/quagga/babeld/xroute.c, revision 1.1
1.1 ! misho 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: Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
! 20:
! 21: Permission is hereby granted, free of charge, to any person obtaining a copy
! 22: of this software and associated documentation files (the "Software"), to deal
! 23: in the Software without restriction, including without limitation the rights
! 24: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! 25: copies of the Software, and to permit persons to whom the Software is
! 26: furnished to do so, subject to the following conditions:
! 27:
! 28: The above copyright notice and this permission notice shall be included in
! 29: all copies or substantial portions of the Software.
! 30:
! 31: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! 32: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! 33: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! 34: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! 35: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! 36: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! 37: THE SOFTWARE.
! 38: */
! 39:
! 40: #include <zebra.h>
! 41: #include "if.h"
! 42: #include "log.h"
! 43:
! 44: #include "babeld.h"
! 45: #include "kernel.h"
! 46: #include "neighbour.h"
! 47: #include "message.h"
! 48: #include "route.h"
! 49: #include "xroute.h"
! 50: #include "util.h"
! 51: #include "babel_interface.h"
! 52:
! 53: static int xroute_add_new_route(unsigned char prefix[16], unsigned char plen,
! 54: unsigned short metric, unsigned int ifindex,
! 55: int proto, int send_updates);
! 56:
! 57: static struct xroute *xroutes;
! 58: static int numxroutes = 0, maxxroutes = 0;
! 59:
! 60: /* Add redistributed route to Babel table. */
! 61: int
! 62: babel_ipv4_route_add (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix,
! 63: unsigned int ifindex, struct in_addr *nexthop)
! 64: {
! 65: unsigned char uchar_prefix[16];
! 66:
! 67: inaddr_to_uchar(uchar_prefix, &prefix->prefix);
! 68: debugf(BABEL_DEBUG_ROUTE, "Adding new ipv4 route comming from Zebra.");
! 69: xroute_add_new_route(uchar_prefix, prefix->prefixlen + 96,
! 70: api->metric, ifindex, 0, 1);
! 71: return 0;
! 72: }
! 73:
! 74: /* Remove redistributed route from Babel table. */
! 75: int
! 76: babel_ipv4_route_delete (struct zapi_ipv4 *api, struct prefix_ipv4 *prefix,
! 77: unsigned int ifindex)
! 78: {
! 79: unsigned char uchar_prefix[16];
! 80: struct xroute *xroute = NULL;
! 81:
! 82: inaddr_to_uchar(uchar_prefix, &prefix->prefix);
! 83: xroute = find_xroute(uchar_prefix, prefix->prefixlen + 96);
! 84: if (xroute != NULL) {
! 85: debugf(BABEL_DEBUG_ROUTE, "Removing ipv4 route (from zebra).");
! 86: flush_xroute(xroute);
! 87: }
! 88: return 0;
! 89: }
! 90:
! 91: /* Add redistributed route to Babel table. */
! 92: int
! 93: babel_ipv6_route_add (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix,
! 94: unsigned int ifindex, struct in6_addr *nexthop)
! 95: {
! 96: unsigned char uchar_prefix[16];
! 97:
! 98: in6addr_to_uchar(uchar_prefix, &prefix->prefix);
! 99: debugf(BABEL_DEBUG_ROUTE, "Adding new route comming from Zebra.");
! 100: xroute_add_new_route(uchar_prefix, prefix->prefixlen, api->metric, ifindex,
! 101: 0, 1);
! 102: return 0;
! 103: }
! 104:
! 105: /* Remove redistributed route from Babel table. */
! 106: int
! 107: babel_ipv6_route_delete (struct zapi_ipv6 *api, struct prefix_ipv6 *prefix,
! 108: unsigned int ifindex)
! 109: {
! 110: unsigned char uchar_prefix[16];
! 111: struct xroute *xroute = NULL;
! 112:
! 113: in6addr_to_uchar(uchar_prefix, &prefix->prefix);
! 114: xroute = find_xroute(uchar_prefix, prefix->prefixlen);
! 115: if (xroute != NULL) {
! 116: debugf(BABEL_DEBUG_ROUTE, "Removing route (from zebra).");
! 117: flush_xroute(xroute);
! 118: }
! 119: return 0;
! 120: }
! 121:
! 122: struct xroute *
! 123: find_xroute(const unsigned char *prefix, unsigned char plen)
! 124: {
! 125: int i;
! 126: for(i = 0; i < numxroutes; i++) {
! 127: if(xroutes[i].plen == plen &&
! 128: memcmp(xroutes[i].prefix, prefix, 16) == 0)
! 129: return &xroutes[i];
! 130: }
! 131: return NULL;
! 132: }
! 133:
! 134: void
! 135: flush_xroute(struct xroute *xroute)
! 136: {
! 137: int i;
! 138:
! 139: i = xroute - xroutes;
! 140: assert(i >= 0 && i < numxroutes);
! 141:
! 142: if(i != numxroutes - 1)
! 143: memcpy(xroutes + i, xroutes + numxroutes - 1, sizeof(struct xroute));
! 144: numxroutes--;
! 145: VALGRIND_MAKE_MEM_UNDEFINED(xroutes + numxroutes, sizeof(struct xroute));
! 146:
! 147: if(numxroutes == 0) {
! 148: free(xroutes);
! 149: xroutes = NULL;
! 150: maxxroutes = 0;
! 151: } else if(maxxroutes > 8 && numxroutes < maxxroutes / 4) {
! 152: struct xroute *new_xroutes;
! 153: int n = maxxroutes / 2;
! 154: new_xroutes = realloc(xroutes, n * sizeof(struct xroute));
! 155: if(new_xroutes == NULL)
! 156: return;
! 157: xroutes = new_xroutes;
! 158: maxxroutes = n;
! 159: }
! 160: }
! 161:
! 162: static int
! 163: add_xroute(unsigned char prefix[16], unsigned char plen,
! 164: unsigned short metric, unsigned int ifindex, int proto)
! 165: {
! 166: struct xroute *xroute = find_xroute(prefix, plen);
! 167: if(xroute) {
! 168: if(xroute->metric <= metric)
! 169: return 0;
! 170: xroute->metric = metric;
! 171: return 1;
! 172: }
! 173:
! 174: if(numxroutes >= maxxroutes) {
! 175: struct xroute *new_xroutes;
! 176: int n = maxxroutes < 1 ? 8 : 2 * maxxroutes;
! 177: new_xroutes = xroutes == NULL ?
! 178: malloc(n * sizeof(struct xroute)) :
! 179: realloc(xroutes, n * sizeof(struct xroute));
! 180: if(new_xroutes == NULL)
! 181: return -1;
! 182: maxxroutes = n;
! 183: xroutes = new_xroutes;
! 184: }
! 185:
! 186: memcpy(xroutes[numxroutes].prefix, prefix, 16);
! 187: xroutes[numxroutes].plen = plen;
! 188: xroutes[numxroutes].metric = metric;
! 189: xroutes[numxroutes].ifindex = ifindex;
! 190: xroutes[numxroutes].proto = proto;
! 191: numxroutes++;
! 192: return 1;
! 193: }
! 194:
! 195: /* Returns an overestimate of the number of xroutes. */
! 196: int
! 197: xroutes_estimate()
! 198: {
! 199: return numxroutes;
! 200: }
! 201:
! 202: void
! 203: for_all_xroutes(void (*f)(struct xroute*, void*), void *closure)
! 204: {
! 205: int i;
! 206:
! 207: for(i = 0; i < numxroutes; i++)
! 208: (*f)(&xroutes[i], closure);
! 209: }
! 210:
! 211: /* add an xroute, verifying some conditions; return 0 if there is no changes */
! 212: static int
! 213: xroute_add_new_route(unsigned char prefix[16], unsigned char plen,
! 214: unsigned short metric, unsigned int ifindex,
! 215: int proto, int send_updates)
! 216: {
! 217: int rc;
! 218: if(martian_prefix(prefix, plen))
! 219: return 0;
! 220: metric = redistribute_filter(prefix, plen, ifindex, proto);
! 221: if(metric < INFINITY) {
! 222: rc = add_xroute(prefix, plen, metric, ifindex, proto);
! 223: if(rc > 0) {
! 224: struct babel_route *route;
! 225: route = find_installed_route(prefix, plen);
! 226: if(route) {
! 227: if(allow_duplicates < 0 ||
! 228: metric < allow_duplicates)
! 229: uninstall_route(route);
! 230: }
! 231: if(send_updates)
! 232: send_update(NULL, 0, prefix, plen);
! 233: return 1;
! 234: }
! 235: }
! 236: return 0;
! 237: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>