Annotation of embedaddon/quagga/ospfd/ospf_zebra.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Zebra connect library for OSPFd
                      3:  * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
                      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
                     19:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
                     20:  * Boston, MA 02111-1307, USA. 
                     21:  */
                     22: 
                     23: #include <zebra.h>
                     24: 
                     25: #include "thread.h"
                     26: #include "command.h"
                     27: #include "network.h"
                     28: #include "prefix.h"
                     29: #include "routemap.h"
                     30: #include "table.h"
                     31: #include "stream.h"
                     32: #include "memory.h"
                     33: #include "zclient.h"
                     34: #include "filter.h"
                     35: #include "plist.h"
                     36: #include "log.h"
                     37: 
                     38: #include "ospfd/ospfd.h"
                     39: #include "ospfd/ospf_interface.h"
                     40: #include "ospfd/ospf_ism.h"
                     41: #include "ospfd/ospf_asbr.h"
                     42: #include "ospfd/ospf_asbr.h"
                     43: #include "ospfd/ospf_abr.h"
                     44: #include "ospfd/ospf_lsa.h"
                     45: #include "ospfd/ospf_dump.h"
                     46: #include "ospfd/ospf_route.h"
                     47: #include "ospfd/ospf_zebra.h"
                     48: #ifdef HAVE_SNMP
                     49: #include "ospfd/ospf_snmp.h"
                     50: #endif /* HAVE_SNMP */
                     51: 
                     52: /* Zebra structure to hold current status. */
                     53: struct zclient *zclient = NULL;
                     54: 
                     55: /* For registering threads. */
                     56: extern struct thread_master *master;
                     57: struct in_addr router_id_zebra;
                     58: 
                     59: /* Router-id update message from zebra. */
                     60: static int
                     61: ospf_router_id_update_zebra (int command, struct zclient *zclient,
                     62:                             zebra_size_t length)
                     63: {
                     64:   struct ospf *ospf;
                     65:   struct prefix router_id;
                     66:   zebra_router_id_update_read(zclient->ibuf,&router_id);
                     67: 
                     68:   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                     69:     {
                     70:       char buf[128];
                     71:       prefix2str(&router_id, buf, sizeof(buf));
                     72:       zlog_debug("Zebra rcvd: router id update %s", buf);
                     73:     }
                     74: 
                     75:   router_id_zebra = router_id.u.prefix4;
                     76: 
                     77:   ospf = ospf_lookup ();
                     78:   
                     79:   if (ospf != NULL)
                     80:     ospf_router_id_update (ospf);
                     81:   
                     82:   return 0;
                     83: }
                     84: 
                     85: /* Inteface addition message from zebra. */
                     86: static int
                     87: ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
                     88: {
                     89:   struct interface *ifp;
                     90: 
                     91:   ifp = zebra_interface_add_read (zclient->ibuf);
                     92: 
                     93:   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                     94:     zlog_debug ("Zebra: interface add %s index %d flags %llx metric %d mtu %d",
                     95:                ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
                     96:                ifp->metric, ifp->mtu);
                     97: 
                     98:   assert (ifp->info);
                     99: 
                    100:   if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
                    101:     {
                    102:       SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
                    103:       IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
                    104:     }
                    105: 
                    106:   ospf_if_update (NULL, ifp);
                    107: 
                    108: #ifdef HAVE_SNMP
                    109:   ospf_snmp_if_update (ifp);
                    110: #endif /* HAVE_SNMP */
                    111: 
                    112:   return 0;
                    113: }
                    114: 
                    115: static int
                    116: ospf_interface_delete (int command, struct zclient *zclient,
                    117:                        zebra_size_t length)
                    118: {
                    119:   struct interface *ifp;
                    120:   struct stream *s;
                    121:   struct route_node *rn;
                    122: 
                    123:   s = zclient->ibuf;
                    124:   /* zebra_interface_state_read() updates interface structure in iflist */
                    125:   ifp = zebra_interface_state_read (s);
                    126: 
                    127:   if (ifp == NULL)
                    128:     return 0;
                    129: 
                    130:   if (if_is_up (ifp))
                    131:     zlog_warn ("Zebra: got delete of %s, but interface is still up",
                    132:                ifp->name);
                    133: 
                    134:   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                    135:     zlog_debug
                    136:       ("Zebra: interface delete %s index %d flags %lld metric %d mtu %d",
                    137:        ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
                    138: 
                    139: #ifdef HAVE_SNMP
                    140:   ospf_snmp_if_delete (ifp);
                    141: #endif /* HAVE_SNMP */
                    142: 
                    143:   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
                    144:     if (rn->info)
                    145:       ospf_if_free ((struct ospf_interface *) rn->info);
                    146: 
                    147:   ifp->ifindex = IFINDEX_INTERNAL;
                    148:   return 0;
                    149: }
                    150: 
                    151: static struct interface *
                    152: zebra_interface_if_lookup (struct stream *s)
                    153: {
                    154:   char ifname_tmp[INTERFACE_NAMSIZ];
                    155: 
                    156:   /* Read interface name. */
                    157:   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
                    158: 
                    159:   /* And look it up. */
                    160:   return if_lookup_by_name_len(ifname_tmp,
                    161:                               strnlen(ifname_tmp, INTERFACE_NAMSIZ));
                    162: }
                    163: 
                    164: static int
                    165: ospf_interface_state_up (int command, struct zclient *zclient,
                    166:                          zebra_size_t length)
                    167: {
                    168:   struct interface *ifp;
                    169:   struct ospf_interface *oi;
                    170:   struct route_node *rn;
                    171: 
                    172:   ifp = zebra_interface_if_lookup (zclient->ibuf);
                    173: 
                    174:   if (ifp == NULL)
                    175:     return 0;
                    176: 
                    177:   /* Interface is already up. */
                    178:   if (if_is_operative (ifp))
                    179:     {
                    180:       /* Temporarily keep ifp values. */
                    181:       struct interface if_tmp;
                    182:       memcpy (&if_tmp, ifp, sizeof (struct interface));
                    183: 
                    184:       zebra_interface_if_set_value (zclient->ibuf, ifp);
                    185: 
                    186:       if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                    187:         zlog_debug ("Zebra: Interface[%s] state update.", ifp->name);
                    188: 
                    189:       if (if_tmp.bandwidth != ifp->bandwidth)
                    190:         {
                    191:           if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                    192:             zlog_debug ("Zebra: Interface[%s] bandwidth change %d -> %d.",
                    193:                        ifp->name, if_tmp.bandwidth, ifp->bandwidth);
                    194: 
                    195:           ospf_if_recalculate_output_cost (ifp);
                    196:         }
                    197: 
                    198:       if (if_tmp.mtu != ifp->mtu)
                    199:         {
                    200:           if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                    201:             zlog_debug ("Zebra: Interface[%s] MTU change %u -> %u.",
                    202:                        ifp->name, if_tmp.mtu, ifp->mtu);
                    203: 
                    204:          /* Must reset the interface (simulate down/up) when MTU changes. */
                    205:           ospf_if_reset(ifp);
                    206:        }
                    207:       return 0;
                    208:     }
                    209: 
                    210:   zebra_interface_if_set_value (zclient->ibuf, ifp);
                    211: 
                    212:   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                    213:     zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name);
                    214: 
                    215:   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
                    216:     {
                    217:       if ((oi = rn->info) == NULL)
                    218:         continue;
                    219: 
                    220:       ospf_if_up (oi);
                    221:     }
                    222: 
                    223:   return 0;
                    224: }
                    225: 
                    226: static int
                    227: ospf_interface_state_down (int command, struct zclient *zclient,
                    228:                            zebra_size_t length)
                    229: {
                    230:   struct interface *ifp;
                    231:   struct ospf_interface *oi;
                    232:   struct route_node *node;
                    233: 
                    234:   ifp = zebra_interface_state_read (zclient->ibuf);
                    235: 
                    236:   if (ifp == NULL)
                    237:     return 0;
                    238: 
                    239:   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                    240:     zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name);
                    241: 
                    242:   for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
                    243:     {
                    244:       if ((oi = node->info) == NULL)
                    245:         continue;
                    246:       ospf_if_down (oi);
                    247:     }
                    248: 
                    249:   return 0;
                    250: }
                    251: 
                    252: static int
                    253: ospf_interface_address_add (int command, struct zclient *zclient,
                    254:                             zebra_size_t length)
                    255: {
                    256:   struct connected *c;
                    257: 
                    258:   c = zebra_interface_address_read (command, zclient->ibuf);
                    259: 
                    260:   if (c == NULL)
                    261:     return 0;
                    262: 
                    263:   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                    264:     {
                    265:       char buf[128];
                    266:       prefix2str(c->address, buf, sizeof(buf));
                    267:       zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);
                    268:     }
                    269: 
                    270:   ospf_if_update (NULL, c->ifp);
                    271: 
                    272: #ifdef HAVE_SNMP
                    273:   ospf_snmp_if_update (c->ifp);
                    274: #endif /* HAVE_SNMP */
                    275: 
                    276:   return 0;
                    277: }
                    278: 
                    279: static int
                    280: ospf_interface_address_delete (int command, struct zclient *zclient,
                    281:                                zebra_size_t length)
                    282: {
                    283:   struct connected *c;
                    284:   struct interface *ifp;
                    285:   struct ospf_interface *oi;
                    286:   struct route_node *rn;
                    287:   struct prefix p;
                    288: 
                    289:   c = zebra_interface_address_read (command, zclient->ibuf);
                    290: 
                    291:   if (c == NULL)
                    292:     return 0;
                    293: 
                    294:   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
                    295:     {
                    296:       char buf[128];
                    297:       prefix2str(c->address, buf, sizeof(buf));
                    298:       zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf);
                    299:     }
                    300: 
                    301:   ifp = c->ifp;
                    302:   p = *c->address;
                    303:   p.prefixlen = IPV4_MAX_PREFIXLEN;
                    304: 
                    305:   rn = route_node_lookup (IF_OIFS (ifp), &p);
                    306:   if (!rn)
                    307:     {
                    308:       connected_free (c);
                    309:       return 0;
                    310:     }
                    311: 
                    312:   assert (rn->info);
                    313:   oi = rn->info;
                    314: 
                    315:   /* Call interface hook functions to clean up */
                    316:   ospf_if_free (oi);
                    317: 
                    318: #ifdef HAVE_SNMP
                    319:   ospf_snmp_if_update (c->ifp);
                    320: #endif /* HAVE_SNMP */
                    321: 
                    322:   connected_free (c);
                    323: 
                    324:   return 0;
                    325: }
                    326: 
                    327: void
                    328: ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
                    329: {
                    330:   u_char message;
                    331:   u_char distance;
                    332:   u_char flags;
                    333:   int psize;
                    334:   struct stream *s;
                    335:   struct ospf_path *path;
                    336:   struct listnode *node;
                    337: 
                    338:   if (zclient->redist[ZEBRA_ROUTE_OSPF])
                    339:     {
                    340:       message = 0;
                    341:       flags = 0;
                    342: 
                    343:       /* OSPF pass nexthop and metric */
                    344:       SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
                    345:       SET_FLAG (message, ZAPI_MESSAGE_METRIC);
                    346: 
                    347:       /* Distance value. */
                    348:       distance = ospf_distance_apply (p, or);
                    349:       if (distance)
                    350:         SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
                    351: 
                    352:       /* Make packet. */
                    353:       s = zclient->obuf;
                    354:       stream_reset (s);
                    355: 
                    356:       /* Put command, type, flags, message. */
                    357:       zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
                    358:       stream_putc (s, ZEBRA_ROUTE_OSPF);
                    359:       stream_putc (s, flags);
                    360:       stream_putc (s, message);
                    361: 
                    362:       /* Put prefix information. */
                    363:       psize = PSIZE (p->prefixlen);
                    364:       stream_putc (s, p->prefixlen);
                    365:       stream_write (s, (u_char *) & p->prefix, psize);
                    366: 
                    367:       /* Nexthop count. */
                    368:       stream_putc (s, or->paths->count);
                    369: 
                    370:       /* Nexthop, ifindex, distance and metric information. */
                    371:       for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
                    372:         {
                    373:           if (path->nexthop.s_addr != INADDR_ANY)
                    374:             {
                    375:               stream_putc (s, ZEBRA_NEXTHOP_IPV4);
                    376:               stream_put_in_addr (s, &path->nexthop);
                    377:             }
                    378:           else
                    379:             {
                    380:               stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
                    381:               if (path->ifindex)
                    382:                 stream_putl (s, path->ifindex);
                    383:               else
                    384:                 stream_putl (s, 0);
                    385:             }
                    386: 
                    387:           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    388:             {
                    389:              char buf[2][INET_ADDRSTRLEN];
                    390:              zlog_debug("Zebra: Route add %s/%d nexthop %s",
                    391:                         inet_ntop(AF_INET, &p->prefix,
                    392:                                   buf[0], sizeof(buf[0])),
                    393:                         p->prefixlen,
                    394:                         inet_ntop(AF_INET, &path->nexthop,
                    395:                                   buf[1], sizeof(buf[1])));
                    396:             }
                    397:         }
                    398: 
                    399:       if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
                    400:         stream_putc (s, distance);
                    401:       if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
                    402:         {
                    403:           if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
                    404:             stream_putl (s, or->cost + or->u.ext.type2_cost);
                    405:           else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
                    406:             stream_putl (s, or->u.ext.type2_cost);
                    407:           else
                    408:             stream_putl (s, or->cost);
                    409:         }
                    410: 
                    411:       stream_putw_at (s, 0, stream_get_endp (s));
                    412: 
                    413:       zclient_send_message(zclient);
                    414:     }
                    415: }
                    416: 
                    417: void
                    418: ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
                    419: {
                    420:   struct zapi_ipv4 api;
                    421:   struct ospf_path *path;
                    422:   struct in_addr *nexthop;
                    423:   struct listnode *node, *nnode;
                    424: 
                    425:   if (zclient->redist[ZEBRA_ROUTE_OSPF])
                    426:     {
                    427:       api.type = ZEBRA_ROUTE_OSPF;
                    428:       api.flags = 0;
                    429:       api.message = 0;
                    430:       api.ifindex_num = 0;
                    431:       api.nexthop_num = 0;
                    432: 
                    433:       for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path))
                    434:         {
                    435:           if (path->nexthop.s_addr != INADDR_ANY)
                    436:             {
                    437:               SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
                    438:               api.nexthop_num = 1;
                    439:               nexthop = &path->nexthop;
                    440:               api.nexthop = &nexthop;
                    441:             }
                    442:           else if (if_lookup_by_index(path->ifindex))
                    443:             {
                    444:               SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
                    445:               api.ifindex_num = 1;
                    446:               api.ifindex = &path->ifindex;
                    447:             }
                    448:           else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) )
                    449:             {
                    450:               zlog_debug("Zebra: no ifp %s %d",
                    451:                          inet_ntoa(p->prefix),
                    452:                          p->prefixlen);
                    453:             }
                    454: 
                    455:           zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
                    456: 
                    457:           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num)
                    458:             {
                    459:              char buf[2][INET_ADDRSTRLEN];
                    460:              zlog_debug("Zebra: Route delete %s/%d nexthop %s",
                    461:                         inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])),
                    462:                         p->prefixlen,
                    463:                         inet_ntop(AF_INET, *api.nexthop,
                    464:                                   buf[1], sizeof(buf[1])));
                    465:             }
                    466:           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num)
                    467:             {
                    468:               zlog_debug ("Zebra: Route delete %s/%d ifindex %d",
                    469:                          inet_ntoa (p->prefix),
                    470:                          p->prefixlen, *api.ifindex);
                    471:             }
                    472:         }
                    473:     }
                    474: }
                    475: 
                    476: void
                    477: ospf_zebra_add_discard (struct prefix_ipv4 *p)
                    478: {
                    479:   struct zapi_ipv4 api;
                    480: 
                    481:   if (zclient->redist[ZEBRA_ROUTE_OSPF])
                    482:     {
                    483:       api.type = ZEBRA_ROUTE_OSPF;
                    484:       api.flags = ZEBRA_FLAG_BLACKHOLE;
                    485:       api.message = 0;
                    486:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
                    487:       api.nexthop_num = 0;
                    488:       api.ifindex_num = 0;
                    489: 
                    490:       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
                    491: 
                    492:       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    493:         zlog_debug ("Zebra: Route add discard %s/%d",
                    494:                    inet_ntoa (p->prefix), p->prefixlen);
                    495:     }
                    496: }
                    497: 
                    498: void
                    499: ospf_zebra_delete_discard (struct prefix_ipv4 *p)
                    500: {
                    501:   struct zapi_ipv4 api;
                    502: 
                    503:   if (zclient->redist[ZEBRA_ROUTE_OSPF])
                    504:     {
                    505:       api.type = ZEBRA_ROUTE_OSPF;
                    506:       api.flags = ZEBRA_FLAG_BLACKHOLE;
                    507:       api.message = 0;
                    508:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
                    509:       api.nexthop_num = 0;
                    510:       api.ifindex_num = 0;
                    511: 
                    512:       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
                    513: 
                    514:       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    515:         zlog_debug ("Zebra: Route delete discard %s/%d",
                    516:                    inet_ntoa (p->prefix), p->prefixlen);
                    517: 
                    518:     }
                    519: }
                    520: 
                    521: int
                    522: ospf_is_type_redistributed (int type)
                    523: {
                    524:   return (DEFAULT_ROUTE_TYPE (type)) ?
                    525:     zclient->default_information : zclient->redist[type];
                    526: }
                    527: 
                    528: int
                    529: ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
                    530: {
                    531:   int force = 0;
                    532: 
                    533:   if (ospf_is_type_redistributed (type))
                    534:     {
                    535:       if (mtype != ospf->dmetric[type].type)
                    536:         {
                    537:           ospf->dmetric[type].type = mtype;
                    538:           force = LSA_REFRESH_FORCE;
                    539:         }
                    540:       if (mvalue != ospf->dmetric[type].value)
                    541:         {
                    542:           ospf->dmetric[type].value = mvalue;
                    543:           force = LSA_REFRESH_FORCE;
                    544:         }
                    545: 
                    546:       ospf_external_lsa_refresh_type (ospf, type, force);
                    547: 
                    548:       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    549:         zlog_debug ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
                    550:                    ospf_redist_string(type),
                    551:                    metric_type (ospf, type), metric_value (ospf, type));
                    552: 
                    553:       return CMD_SUCCESS;
                    554:     }
                    555: 
                    556:   ospf->dmetric[type].type = mtype;
                    557:   ospf->dmetric[type].value = mvalue;
                    558: 
                    559:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
                    560: 
                    561:   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    562:     zlog_debug ("Redistribute[%s]: Start  Type[%d], Metric[%d]",
                    563:                ospf_redist_string(type),
                    564:                metric_type (ospf, type), metric_value (ospf, type));
                    565: 
                    566:   ospf_asbr_status_update (ospf, ++ospf->redistribute);
                    567: 
                    568:   return CMD_SUCCESS;
                    569: }
                    570: 
                    571: int
                    572: ospf_redistribute_unset (struct ospf *ospf, int type)
                    573: {
                    574:   if (type == zclient->redist_default)
                    575:     return CMD_SUCCESS;
                    576: 
                    577:   if (!ospf_is_type_redistributed (type))
                    578:     return CMD_SUCCESS;
                    579: 
                    580:   zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
                    581: 
                    582:   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    583:     zlog_debug ("Redistribute[%s]: Stop",
                    584:                ospf_redist_string(type));
                    585: 
                    586:   ospf->dmetric[type].type = -1;
                    587:   ospf->dmetric[type].value = -1;
                    588: 
                    589:   /* Remove the routes from OSPF table. */
                    590:   ospf_redistribute_withdraw (ospf, type);
                    591: 
                    592:   ospf_asbr_status_update (ospf, --ospf->redistribute);
                    593: 
                    594:   return CMD_SUCCESS;
                    595: }
                    596: 
                    597: int
                    598: ospf_redistribute_default_set (struct ospf *ospf, int originate,
                    599:                                int mtype, int mvalue)
                    600: {
                    601:   ospf->default_originate = originate;
                    602:   ospf->dmetric[DEFAULT_ROUTE].type = mtype;
                    603:   ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
                    604: 
                    605:   if (ospf_is_type_redistributed (DEFAULT_ROUTE))
                    606:     {
                    607:       /* if ospf->default_originate changes value, is calling
                    608:         ospf_external_lsa_refresh_default sufficient to implement
                    609:         the change? */
                    610:       ospf_external_lsa_refresh_default (ospf);
                    611: 
                    612:       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    613:         zlog_debug ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
                    614:                    ospf_redist_string(DEFAULT_ROUTE),
                    615:                    metric_type (ospf, DEFAULT_ROUTE),
                    616:                    metric_value (ospf, DEFAULT_ROUTE));
                    617:       return CMD_SUCCESS;
                    618:     }
                    619: 
                    620:   zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient);
                    621: 
                    622:   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    623:     zlog_debug ("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
                    624:                metric_type (ospf, DEFAULT_ROUTE),
                    625:                metric_value (ospf, DEFAULT_ROUTE));
                    626: 
                    627:   if (ospf->router_id.s_addr == 0)
                    628:     ospf->external_origin |= (1 << DEFAULT_ROUTE);
                    629:   else
                    630:     thread_add_timer (master, ospf_default_originate_timer, ospf, 1);
                    631: 
                    632:   ospf_asbr_status_update (ospf, ++ospf->redistribute);
                    633: 
                    634:   return CMD_SUCCESS;
                    635: }
                    636: 
                    637: int
                    638: ospf_redistribute_default_unset (struct ospf *ospf)
                    639: {
                    640:   if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
                    641:     return CMD_SUCCESS;
                    642: 
                    643:   ospf->default_originate = DEFAULT_ORIGINATE_NONE;
                    644:   ospf->dmetric[DEFAULT_ROUTE].type = -1;
                    645:   ospf->dmetric[DEFAULT_ROUTE].value = -1;
                    646: 
                    647:   zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
                    648: 
                    649:   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    650:     zlog_debug ("Redistribute[DEFAULT]: Stop");
                    651: 
                    652:   ospf_asbr_status_update (ospf, --ospf->redistribute);
                    653: 
                    654:   return CMD_SUCCESS;
                    655: }
                    656: 
                    657: static int
                    658: ospf_external_lsa_originate_check (struct ospf *ospf,
                    659:                                    struct external_info *ei)
                    660: {
                    661:   /* If prefix is multicast, then do not originate LSA. */
                    662:   if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
                    663:     {
                    664:       zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
                    665:                  "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
                    666:       return 0;
                    667:     }
                    668: 
                    669:   /* Take care of default-originate. */
                    670:   if (is_prefix_default (&ei->p))
                    671:     if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
                    672:       {
                    673:         zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "
                    674:                    "for default");
                    675:         return 0;
                    676:       }
                    677: 
                    678:   return 1;
                    679: }
                    680: 
                    681: /* If connected prefix is OSPF enable interface, then do not announce. */
                    682: int
                    683: ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei)
                    684: {
                    685:   struct listnode *node;
                    686:   struct ospf_interface *oi;
                    687: 
                    688: 
                    689:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
                    690:       if (prefix_match (oi->address, (struct prefix *) &ei->p))
                    691:           return 0;
                    692:   return 1;
                    693: }
                    694: 
                    695: /* return 1 if external LSA must be originated, 0 otherwise */
                    696: int
                    697: ospf_redistribute_check (struct ospf *ospf,
                    698:                          struct external_info *ei, int *changed)
                    699: {
                    700:   struct route_map_set_values save_values;
                    701:   struct prefix_ipv4 *p = &ei->p;
                    702:   u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
                    703: 
                    704:   if (changed)
                    705:     *changed = 0;
                    706: 
                    707:   if (!ospf_external_lsa_originate_check (ospf, ei))
                    708:     return 0;
                    709: 
                    710:   /* Take care connected route. */
                    711:   if (type == ZEBRA_ROUTE_CONNECT &&
                    712:       !ospf_distribute_check_connected (ospf, ei))
                    713:     return 0;
                    714: 
                    715:   if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
                    716:     /* distirbute-list exists, but access-list may not? */
                    717:     if (DISTRIBUTE_LIST (ospf, type))
                    718:       if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
                    719:         {
                    720:           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    721:             zlog_debug ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
                    722:                        ospf_redist_string(type),
                    723:                        inet_ntoa (p->prefix), p->prefixlen);
                    724:           return 0;
                    725:         }
                    726: 
                    727:   save_values = ei->route_map_set;
                    728:   ospf_reset_route_map_set_values (&ei->route_map_set);
                    729: 
                    730:   /* apply route-map if needed */
                    731:   if (ROUTEMAP_NAME (ospf, type))
                    732:     {
                    733:       int ret;
                    734: 
                    735:       ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
                    736:                              RMAP_OSPF, ei);
                    737: 
                    738:       if (ret == RMAP_DENYMATCH)
                    739:         {
                    740:           ei->route_map_set = save_values;
                    741:           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    742:             zlog_debug ("Redistribute[%s]: %s/%d filtered by route-map.",
                    743:                        ospf_redist_string(type),
                    744:                        inet_ntoa (p->prefix), p->prefixlen);
                    745:           return 0;
                    746:         }
                    747: 
                    748:       /* check if 'route-map set' changed something */
                    749:       if (changed)
                    750:         *changed = !ospf_route_map_set_compare (&ei->route_map_set,
                    751:                                                 &save_values);
                    752:     }
                    753: 
                    754:   return 1;
                    755: }
                    756: 
                    757: /* OSPF route-map set for redistribution */
                    758: void
                    759: ospf_routemap_set (struct ospf *ospf, int type, const char *name)
                    760: {
                    761:   if (ROUTEMAP_NAME (ospf, type))
                    762:     free (ROUTEMAP_NAME (ospf, type));
                    763: 
                    764:   ROUTEMAP_NAME (ospf, type) = strdup (name);
                    765:   ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
                    766: }
                    767: 
                    768: void
                    769: ospf_routemap_unset (struct ospf *ospf, int type)
                    770: {
                    771:   if (ROUTEMAP_NAME (ospf, type))
                    772:     free (ROUTEMAP_NAME (ospf, type));
                    773: 
                    774:   ROUTEMAP_NAME (ospf, type) = NULL;
                    775:   ROUTEMAP (ospf, type) = NULL;
                    776: }
                    777: 
                    778: /* Zebra route add and delete treatment. */
                    779: static int
                    780: ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
                    781:                       zebra_size_t length)
                    782: {
                    783:   struct stream *s;
                    784:   struct zapi_ipv4 api;
                    785:   unsigned long ifindex;
                    786:   struct in_addr nexthop;
                    787:   struct prefix_ipv4 p;
                    788:   struct external_info *ei;
                    789:   struct ospf *ospf;
                    790: 
                    791:   s = zclient->ibuf;
                    792:   ifindex = 0;
                    793:   nexthop.s_addr = 0;
                    794: 
                    795:   /* Type, flags, message. */
                    796:   api.type = stream_getc (s);
                    797:   api.flags = stream_getc (s);
                    798:   api.message = stream_getc (s);
                    799: 
                    800:   /* IPv4 prefix. */
                    801:   memset (&p, 0, sizeof (struct prefix_ipv4));
                    802:   p.family = AF_INET;
                    803:   p.prefixlen = stream_getc (s);
                    804:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                    805: 
                    806:   if (IPV4_NET127(ntohl(p.prefix.s_addr)))
                    807:     return 0;
                    808: 
                    809:   /* Nexthop, ifindex, distance, metric. */
                    810:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
                    811:     {
                    812:       api.nexthop_num = stream_getc (s);
                    813:       nexthop.s_addr = stream_get_ipv4 (s);
                    814:     }
                    815:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
                    816:     {
                    817:       api.ifindex_num = stream_getc (s);
                    818:       /* XXX assert(api.ifindex_num == 1); */
                    819:       ifindex = stream_getl (s);
                    820:     }
                    821:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                    822:     api.distance = stream_getc (s);
                    823:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                    824:     api.metric = stream_getl (s);
                    825: 
                    826:   ospf = ospf_lookup ();
                    827:   if (ospf == NULL)
                    828:     return 0;
                    829: 
                    830:   if (command == ZEBRA_IPV4_ROUTE_ADD)
                    831:     {
                    832:       /* XXX|HACK|TODO|FIXME:
                    833:        * Maybe we should ignore reject/blackhole routes? Testing shows that
                    834:        * there is no problems though and this is only way to "summarize"
                    835:        * routes in ASBR at the moment. Maybe we need just a better generalised
                    836:        * solution for these types?
                    837:        *
                    838:        * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
                    839:        *     || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
                    840:        * return 0;
                    841:        */
                    842:         
                    843:       ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
                    844: 
                    845:       if (ospf->router_id.s_addr == 0)
                    846:         /* Set flags to generate AS-external-LSA originate event
                    847:            for each redistributed protocols later. */
                    848:         ospf->external_origin |= (1 << api.type);
                    849:       else
                    850:         {
                    851:           if (ei)
                    852:             {
                    853:               if (is_prefix_default (&p))
                    854:                 ospf_external_lsa_refresh_default (ospf);
                    855:               else
                    856:                 {
                    857:                   struct ospf_lsa *current;
                    858: 
                    859:                   current = ospf_external_info_find_lsa (ospf, &ei->p);
                    860:                   if (!current)
                    861:                     ospf_external_lsa_originate (ospf, ei);
                    862:                   else if (IS_LSA_MAXAGE (current))
                    863:                     ospf_external_lsa_refresh (ospf, current,
                    864:                                                ei, LSA_REFRESH_FORCE);
                    865:                   else
                    866:                     zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
                    867:                                inet_ntoa (p.prefix));
                    868:                 }
                    869:             }
                    870:         }
                    871:     }
                    872:   else                          /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
                    873:     {
                    874:       ospf_external_info_delete (api.type, p);
                    875:       if (is_prefix_default (&p))
                    876:         ospf_external_lsa_refresh_default (ospf);
                    877:       else
                    878:         ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */);
                    879:     }
                    880: 
                    881:   return 0;
                    882: }
                    883: 
                    884: 
                    885: int
                    886: ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name)
                    887: {
                    888:   /* Lookup access-list for distribute-list. */
                    889:   DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
                    890: 
                    891:   /* Clear previous distribute-name. */
                    892:   if (DISTRIBUTE_NAME (ospf, type))
                    893:     free (DISTRIBUTE_NAME (ospf, type));
                    894: 
                    895:   /* Set distribute-name. */
                    896:   DISTRIBUTE_NAME (ospf, type) = strdup (name);
                    897: 
                    898:   /* If access-list have been set, schedule update timer. */
                    899:   if (DISTRIBUTE_LIST (ospf, type))
                    900:     ospf_distribute_list_update (ospf, type);
                    901: 
                    902:   return CMD_SUCCESS;
                    903: }
                    904: 
                    905: int
                    906: ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
                    907: {
                    908:   /* Schedule update timer. */
                    909:   if (DISTRIBUTE_LIST (ospf, type))
                    910:     ospf_distribute_list_update (ospf, type);
                    911: 
                    912:   /* Unset distribute-list. */
                    913:   DISTRIBUTE_LIST (ospf, type) = NULL;
                    914: 
                    915:   /* Clear distribute-name. */
                    916:   if (DISTRIBUTE_NAME (ospf, type))
                    917:     free (DISTRIBUTE_NAME (ospf, type));
                    918: 
                    919:   DISTRIBUTE_NAME (ospf, type) = NULL;
                    920: 
                    921:   return CMD_SUCCESS;
                    922: }
                    923: 
                    924: /* distribute-list update timer. */
                    925: static int
                    926: ospf_distribute_list_update_timer (struct thread *thread)
                    927: {
                    928:   struct route_node *rn;
                    929:   struct external_info *ei;
                    930:   struct route_table *rt;
                    931:   struct ospf_lsa *lsa;
                    932:   int type, default_refresh = 0;
                    933:   struct ospf *ospf;
                    934: 
                    935:   ospf = ospf_lookup ();
                    936:   if (ospf == NULL)
                    937:     return 0;
                    938: 
                    939:   ospf->t_distribute_update = NULL;
                    940: 
                    941:   zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
                    942: 
                    943:   /* foreach all external info. */
                    944:   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
                    945:     {
                    946:       rt = EXTERNAL_INFO (type);
                    947:       if (!rt)
                    948:        continue;
                    949:       for (rn = route_top (rt); rn; rn = route_next (rn))
                    950:        if ((ei = rn->info) != NULL)
                    951:          {
                    952:            if (is_prefix_default (&ei->p))
                    953:              default_refresh = 1;
                    954:            else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
                    955:              ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
                    956:            else
                    957:              ospf_external_lsa_originate (ospf, ei);
                    958:          }
                    959:     }
                    960:   if (default_refresh)
                    961:     ospf_external_lsa_refresh_default (ospf);
                    962:   return 0;
                    963: }
                    964: 
                    965: #define OSPF_DISTRIBUTE_UPDATE_DELAY 5
                    966: 
                    967: /* Update distribute-list and set timer to apply access-list. */
                    968: void
                    969: ospf_distribute_list_update (struct ospf *ospf, int type)
                    970: {
                    971:   struct route_table *rt;
                    972: 
                    973:   /* External info does not exist. */
                    974:   if (!(rt = EXTERNAL_INFO (type)))
                    975:     return;
                    976: 
                    977:   /* If exists previously invoked thread, then let it continue. */
                    978:   if (ospf->t_distribute_update)
                    979:     return;
                    980: 
                    981:   /* Set timer. */
                    982:   ospf->t_distribute_update =
                    983:     thread_add_timer (master, ospf_distribute_list_update_timer,
                    984:                       (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
                    985: }
                    986: 
                    987: /* If access-list is updated, apply some check. */
                    988: static void
                    989: ospf_filter_update (struct access_list *access)
                    990: {
                    991:   struct ospf *ospf;
                    992:   int type;
                    993:   int abr_inv = 0;
                    994:   struct ospf_area *area;
                    995:   struct listnode *node;
                    996: 
                    997:   /* If OSPF instatnce does not exist, return right now. */
                    998:   ospf = ospf_lookup ();
                    999:   if (ospf == NULL)
                   1000:     return;
                   1001: 
                   1002:   /* Update distribute-list, and apply filter. */
                   1003:   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
                   1004:     {
                   1005:       if (ROUTEMAP (ospf, type) != NULL)
                   1006:         {
                   1007:           /* if route-map is not NULL it may be using this access list */
                   1008:           ospf_distribute_list_update (ospf, type);
                   1009:           continue;
                   1010:         }
                   1011: 
                   1012:       /* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
                   1013:        * but no distribute list. */
                   1014:       if (type == ZEBRA_ROUTE_MAX)
                   1015:        break;
                   1016: 
                   1017:       if (DISTRIBUTE_NAME (ospf, type))
                   1018:         {
                   1019:           /* Keep old access-list for distribute-list. */
                   1020:           struct access_list *old = DISTRIBUTE_LIST (ospf, type);
                   1021: 
                   1022:           /* Update access-list for distribute-list. */
                   1023:           DISTRIBUTE_LIST (ospf, type) =
                   1024:             access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
                   1025: 
                   1026:           /* No update for this distribute type. */
                   1027:           if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
                   1028:             continue;
                   1029: 
                   1030:           /* Schedule distribute-list update timer. */
                   1031:           if (DISTRIBUTE_LIST (ospf, type) == NULL ||
                   1032:               strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
                   1033:             ospf_distribute_list_update (ospf, type);
                   1034:         }
                   1035:     }
                   1036: 
                   1037:   /* Update Area access-list. */
                   1038:   for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
                   1039:     {
                   1040:       if (EXPORT_NAME (area))
                   1041:         {
                   1042:           EXPORT_LIST (area) = NULL;
                   1043:           abr_inv++;
                   1044:         }
                   1045: 
                   1046:       if (IMPORT_NAME (area))
                   1047:         {
                   1048:           IMPORT_LIST (area) = NULL;
                   1049:           abr_inv++;
                   1050:         }
                   1051:     }
                   1052: 
                   1053:   /* Schedule ABR tasks -- this will be changed -- takada. */
                   1054:   if (IS_OSPF_ABR (ospf) && abr_inv)
                   1055:     ospf_schedule_abr_task (ospf);
                   1056: }
                   1057: 
                   1058: /* If prefix-list is updated, do some updates. */
                   1059: void
                   1060: ospf_prefix_list_update (struct prefix_list *plist)
                   1061: {
                   1062:   struct ospf *ospf;
                   1063:   int type;
                   1064:   int abr_inv = 0;
                   1065:   struct ospf_area *area;
                   1066:   struct listnode *node;
                   1067: 
                   1068:   /* If OSPF instatnce does not exist, return right now. */
                   1069:   ospf = ospf_lookup ();
                   1070:   if (ospf == NULL)
                   1071:     return;
                   1072: 
                   1073:   /* Update all route-maps which are used as redistribution filters.
                   1074:    * They might use prefix-list.
                   1075:    */
                   1076:   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
                   1077:     {
                   1078:       if (ROUTEMAP (ospf, type) != NULL)
                   1079:         {
                   1080:           /* If route-map is not NULL it may be using this prefix list */
                   1081:           ospf_distribute_list_update (ospf, type);
                   1082:           continue;
                   1083:         }
                   1084:     }
                   1085: 
                   1086:   /* Update area filter-lists. */
                   1087:   for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
                   1088:     {
                   1089:       /* Update filter-list in. */
                   1090:       if (PREFIX_NAME_IN (area))
                   1091:         if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0)
                   1092:           {
                   1093:             PREFIX_LIST_IN (area) =
                   1094:               prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area));
                   1095:             abr_inv++;
                   1096:           }
                   1097: 
                   1098:       /* Update filter-list out. */
                   1099:       if (PREFIX_NAME_OUT (area))
                   1100:         if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0)
                   1101:           {
                   1102:             PREFIX_LIST_IN (area) =
                   1103:               prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area));
                   1104:             abr_inv++;
                   1105:           }
                   1106:     }
                   1107: 
                   1108:   /* Schedule ABR task. */
                   1109:   if (IS_OSPF_ABR (ospf) && abr_inv)
                   1110:     ospf_schedule_abr_task (ospf);
                   1111: }
                   1112: 
                   1113: static struct ospf_distance *
                   1114: ospf_distance_new (void)
                   1115: {
                   1116:   return XCALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
                   1117: }
                   1118: 
                   1119: static void
                   1120: ospf_distance_free (struct ospf_distance *odistance)
                   1121: {
                   1122:   XFREE (MTYPE_OSPF_DISTANCE, odistance);
                   1123: }
                   1124: 
                   1125: int
                   1126: ospf_distance_set (struct vty *vty, struct ospf *ospf, 
                   1127:                    const char *distance_str,
                   1128:                    const char *ip_str, 
                   1129:                    const char *access_list_str)
                   1130: {
                   1131:   int ret;
                   1132:   struct prefix_ipv4 p;
                   1133:   u_char distance;
                   1134:   struct route_node *rn;
                   1135:   struct ospf_distance *odistance;
                   1136: 
                   1137:   ret = str2prefix_ipv4 (ip_str, &p);
                   1138:   if (ret == 0)
                   1139:     {
                   1140:       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
                   1141:       return CMD_WARNING;
                   1142:     }
                   1143: 
                   1144:   distance = atoi (distance_str);
                   1145: 
                   1146:   /* Get OSPF distance node. */
                   1147:   rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
                   1148:   if (rn->info)
                   1149:     {
                   1150:       odistance = rn->info;
                   1151:       route_unlock_node (rn);
                   1152:     }
                   1153:   else
                   1154:     {
                   1155:       odistance = ospf_distance_new ();
                   1156:       rn->info = odistance;
                   1157:     }
                   1158: 
                   1159:   /* Set distance value. */
                   1160:   odistance->distance = distance;
                   1161: 
                   1162:   /* Reset access-list configuration. */
                   1163:   if (odistance->access_list)
                   1164:     {
                   1165:       free (odistance->access_list);
                   1166:       odistance->access_list = NULL;
                   1167:     }
                   1168:   if (access_list_str)
                   1169:     odistance->access_list = strdup (access_list_str);
                   1170: 
                   1171:   return CMD_SUCCESS;
                   1172: }
                   1173: 
                   1174: int
                   1175: ospf_distance_unset (struct vty *vty, struct ospf *ospf, 
                   1176:                      const char *distance_str,
                   1177:                      const char *ip_str, char 
                   1178:                      const *access_list_str)
                   1179: {
                   1180:   int ret;
                   1181:   struct prefix_ipv4 p;
                   1182:   u_char distance;
                   1183:   struct route_node *rn;
                   1184:   struct ospf_distance *odistance;
                   1185: 
                   1186:   ret = str2prefix_ipv4 (ip_str, &p);
                   1187:   if (ret == 0)
                   1188:     {
                   1189:       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
                   1190:       return CMD_WARNING;
                   1191:     }
                   1192: 
                   1193:   distance = atoi (distance_str);
                   1194: 
                   1195:   rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p);
                   1196:   if (!rn)
                   1197:     {
                   1198:       vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
                   1199:       return CMD_WARNING;
                   1200:     }
                   1201: 
                   1202:   odistance = rn->info;
                   1203: 
                   1204:   if (odistance->access_list)
                   1205:     free (odistance->access_list);
                   1206:   ospf_distance_free (odistance);
                   1207: 
                   1208:   rn->info = NULL;
                   1209:   route_unlock_node (rn);
                   1210:   route_unlock_node (rn);
                   1211: 
                   1212:   return CMD_SUCCESS;
                   1213: }
                   1214: 
                   1215: void
                   1216: ospf_distance_reset (struct ospf *ospf)
                   1217: {
                   1218:   struct route_node *rn;
                   1219:   struct ospf_distance *odistance;
                   1220: 
                   1221:   for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
                   1222:     if ((odistance = rn->info) != NULL)
                   1223:       {
                   1224:         if (odistance->access_list)
                   1225:           free (odistance->access_list);
                   1226:         ospf_distance_free (odistance);
                   1227:         rn->info = NULL;
                   1228:         route_unlock_node (rn);
                   1229:       }
                   1230: }
                   1231: 
                   1232: u_char
                   1233: ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
                   1234: {
                   1235:   struct ospf *ospf;
                   1236: 
                   1237:   ospf = ospf_lookup ();
                   1238:   if (ospf == NULL)
                   1239:     return 0;
                   1240: 
                   1241:   if (ospf->distance_intra)
                   1242:     if (or->path_type == OSPF_PATH_INTRA_AREA)
                   1243:       return ospf->distance_intra;
                   1244: 
                   1245:   if (ospf->distance_inter)
                   1246:     if (or->path_type == OSPF_PATH_INTER_AREA)
                   1247:       return ospf->distance_inter;
                   1248: 
                   1249:   if (ospf->distance_external)
                   1250:     if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
                   1251:         || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
                   1252:       return ospf->distance_external;
                   1253: 
                   1254:   if (ospf->distance_all)
                   1255:     return ospf->distance_all;
                   1256: 
                   1257:   return 0;
                   1258: }
                   1259: 
                   1260: void
                   1261: ospf_zebra_init ()
                   1262: {
                   1263:   /* Allocate zebra structure. */
                   1264:   zclient = zclient_new ();
                   1265:   zclient_init (zclient, ZEBRA_ROUTE_OSPF);
                   1266:   zclient->router_id_update = ospf_router_id_update_zebra;
                   1267:   zclient->interface_add = ospf_interface_add;
                   1268:   zclient->interface_delete = ospf_interface_delete;
                   1269:   zclient->interface_up = ospf_interface_state_up;
                   1270:   zclient->interface_down = ospf_interface_state_down;
                   1271:   zclient->interface_address_add = ospf_interface_address_add;
                   1272:   zclient->interface_address_delete = ospf_interface_address_delete;
                   1273:   zclient->ipv4_route_add = ospf_zebra_read_ipv4;
                   1274:   zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
                   1275: 
                   1276:   access_list_add_hook (ospf_filter_update);
                   1277:   access_list_delete_hook (ospf_filter_update);
                   1278:   prefix_list_add_hook (ospf_prefix_list_update);
                   1279:   prefix_list_delete_hook (ospf_prefix_list_update);
                   1280: }

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