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

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
1.1.1.3 ! misho     136:       ("Zebra: interface delete %s index %d flags %llx metric %d mtu %d",
        !           137:        ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
1.1       misho     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);
1.1.1.2   misho     361:       stream_putw (s, SAFI_UNICAST);
1.1       misho     362: 
                    363:       /* Put prefix information. */
                    364:       psize = PSIZE (p->prefixlen);
                    365:       stream_putc (s, p->prefixlen);
                    366:       stream_write (s, (u_char *) & p->prefix, psize);
                    367: 
                    368:       /* Nexthop count. */
                    369:       stream_putc (s, or->paths->count);
                    370: 
                    371:       /* Nexthop, ifindex, distance and metric information. */
                    372:       for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
                    373:         {
1.1.1.3 ! misho     374:           if (path->nexthop.s_addr != INADDR_ANY &&
        !           375:              path->ifindex != 0)
        !           376:             {
        !           377:               stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX);
        !           378:               stream_put_in_addr (s, &path->nexthop);
        !           379:              stream_putl (s, path->ifindex);
        !           380:             }
        !           381:           else if (path->nexthop.s_addr != INADDR_ANY)
1.1       misho     382:             {
                    383:               stream_putc (s, ZEBRA_NEXTHOP_IPV4);
                    384:               stream_put_in_addr (s, &path->nexthop);
                    385:             }
                    386:           else
                    387:             {
                    388:               stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
                    389:               if (path->ifindex)
                    390:                 stream_putl (s, path->ifindex);
                    391:               else
                    392:                 stream_putl (s, 0);
                    393:             }
                    394: 
                    395:           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    396:             {
                    397:              char buf[2][INET_ADDRSTRLEN];
                    398:              zlog_debug("Zebra: Route add %s/%d nexthop %s",
                    399:                         inet_ntop(AF_INET, &p->prefix,
                    400:                                   buf[0], sizeof(buf[0])),
                    401:                         p->prefixlen,
                    402:                         inet_ntop(AF_INET, &path->nexthop,
                    403:                                   buf[1], sizeof(buf[1])));
                    404:             }
                    405:         }
                    406: 
                    407:       if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
                    408:         stream_putc (s, distance);
                    409:       if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
                    410:         {
                    411:           if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
                    412:             stream_putl (s, or->cost + or->u.ext.type2_cost);
                    413:           else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
                    414:             stream_putl (s, or->u.ext.type2_cost);
                    415:           else
                    416:             stream_putl (s, or->cost);
                    417:         }
                    418: 
                    419:       stream_putw_at (s, 0, stream_get_endp (s));
                    420: 
                    421:       zclient_send_message(zclient);
                    422:     }
                    423: }
                    424: 
                    425: void
                    426: ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
                    427: {
1.1.1.3 ! misho     428:   u_char message;
        !           429:   u_char distance;
        !           430:   u_char flags;
        !           431:   int psize;
        !           432:   struct stream *s;
1.1       misho     433:   struct ospf_path *path;
1.1.1.3 ! misho     434:   struct listnode *node;
1.1       misho     435: 
                    436:   if (zclient->redist[ZEBRA_ROUTE_OSPF])
                    437:     {
1.1.1.3 ! misho     438:       message = 0;
        !           439:       flags = 0;
        !           440:       /* Distance value. */
        !           441:       distance = ospf_distance_apply (p, or);
        !           442:       /* Make packet. */
        !           443:       s = zclient->obuf;
        !           444:       stream_reset (s);
1.1       misho     445: 
1.1.1.3 ! misho     446:       /* Put command, type, flags, message. */
        !           447:       zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE);
        !           448:       stream_putc (s, ZEBRA_ROUTE_OSPF);
        !           449:       stream_putc (s, flags);
        !           450:       stream_putc (s, message);
        !           451:       stream_putw (s, SAFI_UNICAST);
1.1       misho     452: 
1.1.1.3 ! misho     453:       /* Put prefix information. */
        !           454:       psize = PSIZE (p->prefixlen);
        !           455:       stream_putc (s, p->prefixlen);
        !           456:       stream_write (s, (u_char *) & p->prefix, psize);
1.1       misho     457: 
1.1.1.3 ! misho     458:       /* Nexthop count. */
        !           459:       stream_putc (s, or->paths->count);
        !           460: 
        !           461:       /* Nexthop, ifindex, distance and metric information. */
        !           462:       for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
        !           463:        {
        !           464:          if (path->nexthop.s_addr != INADDR_ANY &&
        !           465:              path->ifindex != 0)
        !           466:            {
        !           467:              stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX);
        !           468:              stream_put_in_addr (s, &path->nexthop);
        !           469:              stream_putl (s, path->ifindex);
        !           470:            }
        !           471:          else if (path->nexthop.s_addr != INADDR_ANY)
        !           472:            {
        !           473:              stream_putc (s, ZEBRA_NEXTHOP_IPV4);
        !           474:              stream_put_in_addr (s, &path->nexthop);
        !           475:            }
        !           476:          else
        !           477:            {
        !           478:              stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
        !           479:              stream_putl (s, path->ifindex);
        !           480:            }
        !           481: 
        !           482:          if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
        !           483:            {
1.1       misho     484:              char buf[2][INET_ADDRSTRLEN];
1.1.1.3 ! misho     485:              zlog_debug("Zebra: Route add %s/%d nexthop %s",
        !           486:                         inet_ntop(AF_INET, &p->prefix,
        !           487:                                   buf[0], sizeof(buf[0])),
1.1       misho     488:                         p->prefixlen,
1.1.1.3 ! misho     489:                         inet_ntop(AF_INET, &path->nexthop,
1.1       misho     490:                                   buf[1], sizeof(buf[1])));
1.1.1.3 ! misho     491:            }
        !           492:        }
        !           493: 
        !           494:       if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
        !           495:        stream_putc (s, distance);
        !           496:       if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
        !           497:        {
        !           498:          if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
        !           499:            stream_putl (s, or->cost + or->u.ext.type2_cost);
        !           500:          else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
        !           501:            stream_putl (s, or->u.ext.type2_cost);
        !           502:          else
        !           503:            stream_putl (s, or->cost);
        !           504:        }
        !           505: 
        !           506:       stream_putw_at (s, 0, stream_get_endp (s));
        !           507: 
        !           508:       zclient_send_message(zclient);
1.1       misho     509:     }
                    510: }
                    511: 
                    512: void
                    513: ospf_zebra_add_discard (struct prefix_ipv4 *p)
                    514: {
                    515:   struct zapi_ipv4 api;
                    516: 
                    517:   if (zclient->redist[ZEBRA_ROUTE_OSPF])
                    518:     {
                    519:       api.type = ZEBRA_ROUTE_OSPF;
                    520:       api.flags = ZEBRA_FLAG_BLACKHOLE;
                    521:       api.message = 0;
1.1.1.2   misho     522:       api.safi = SAFI_UNICAST;
1.1       misho     523:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
                    524:       api.nexthop_num = 0;
                    525:       api.ifindex_num = 0;
                    526: 
                    527:       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
                    528: 
                    529:       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    530:         zlog_debug ("Zebra: Route add discard %s/%d",
                    531:                    inet_ntoa (p->prefix), p->prefixlen);
                    532:     }
                    533: }
                    534: 
                    535: void
                    536: ospf_zebra_delete_discard (struct prefix_ipv4 *p)
                    537: {
                    538:   struct zapi_ipv4 api;
                    539: 
                    540:   if (zclient->redist[ZEBRA_ROUTE_OSPF])
                    541:     {
                    542:       api.type = ZEBRA_ROUTE_OSPF;
                    543:       api.flags = ZEBRA_FLAG_BLACKHOLE;
                    544:       api.message = 0;
1.1.1.2   misho     545:       api.safi = SAFI_UNICAST;
1.1       misho     546:       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
                    547:       api.nexthop_num = 0;
                    548:       api.ifindex_num = 0;
                    549: 
                    550:       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
                    551: 
                    552:       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    553:         zlog_debug ("Zebra: Route delete discard %s/%d",
                    554:                    inet_ntoa (p->prefix), p->prefixlen);
                    555: 
                    556:     }
                    557: }
                    558: 
                    559: int
                    560: ospf_is_type_redistributed (int type)
                    561: {
                    562:   return (DEFAULT_ROUTE_TYPE (type)) ?
                    563:     zclient->default_information : zclient->redist[type];
                    564: }
                    565: 
                    566: int
                    567: ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
                    568: {
                    569:   int force = 0;
                    570: 
                    571:   if (ospf_is_type_redistributed (type))
                    572:     {
                    573:       if (mtype != ospf->dmetric[type].type)
                    574:         {
                    575:           ospf->dmetric[type].type = mtype;
                    576:           force = LSA_REFRESH_FORCE;
                    577:         }
                    578:       if (mvalue != ospf->dmetric[type].value)
                    579:         {
                    580:           ospf->dmetric[type].value = mvalue;
                    581:           force = LSA_REFRESH_FORCE;
                    582:         }
                    583: 
                    584:       ospf_external_lsa_refresh_type (ospf, type, force);
                    585: 
                    586:       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    587:         zlog_debug ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
                    588:                    ospf_redist_string(type),
                    589:                    metric_type (ospf, type), metric_value (ospf, type));
                    590: 
                    591:       return CMD_SUCCESS;
                    592:     }
                    593: 
                    594:   ospf->dmetric[type].type = mtype;
                    595:   ospf->dmetric[type].value = mvalue;
                    596: 
                    597:   zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
                    598: 
                    599:   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    600:     zlog_debug ("Redistribute[%s]: Start  Type[%d], Metric[%d]",
                    601:                ospf_redist_string(type),
                    602:                metric_type (ospf, type), metric_value (ospf, type));
                    603: 
                    604:   ospf_asbr_status_update (ospf, ++ospf->redistribute);
                    605: 
                    606:   return CMD_SUCCESS;
                    607: }
                    608: 
                    609: int
                    610: ospf_redistribute_unset (struct ospf *ospf, int type)
                    611: {
                    612:   if (type == zclient->redist_default)
                    613:     return CMD_SUCCESS;
                    614: 
                    615:   if (!ospf_is_type_redistributed (type))
                    616:     return CMD_SUCCESS;
                    617: 
                    618:   zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
                    619: 
                    620:   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    621:     zlog_debug ("Redistribute[%s]: Stop",
                    622:                ospf_redist_string(type));
                    623: 
                    624:   ospf->dmetric[type].type = -1;
                    625:   ospf->dmetric[type].value = -1;
                    626: 
                    627:   /* Remove the routes from OSPF table. */
                    628:   ospf_redistribute_withdraw (ospf, type);
                    629: 
                    630:   ospf_asbr_status_update (ospf, --ospf->redistribute);
                    631: 
                    632:   return CMD_SUCCESS;
                    633: }
                    634: 
                    635: int
                    636: ospf_redistribute_default_set (struct ospf *ospf, int originate,
                    637:                                int mtype, int mvalue)
                    638: {
                    639:   ospf->default_originate = originate;
                    640:   ospf->dmetric[DEFAULT_ROUTE].type = mtype;
                    641:   ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
                    642: 
                    643:   if (ospf_is_type_redistributed (DEFAULT_ROUTE))
                    644:     {
                    645:       /* if ospf->default_originate changes value, is calling
                    646:         ospf_external_lsa_refresh_default sufficient to implement
                    647:         the change? */
                    648:       ospf_external_lsa_refresh_default (ospf);
                    649: 
                    650:       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    651:         zlog_debug ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
                    652:                    ospf_redist_string(DEFAULT_ROUTE),
                    653:                    metric_type (ospf, DEFAULT_ROUTE),
                    654:                    metric_value (ospf, DEFAULT_ROUTE));
                    655:       return CMD_SUCCESS;
                    656:     }
                    657: 
                    658:   zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient);
                    659: 
                    660:   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    661:     zlog_debug ("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
                    662:                metric_type (ospf, DEFAULT_ROUTE),
                    663:                metric_value (ospf, DEFAULT_ROUTE));
                    664: 
                    665:   if (ospf->router_id.s_addr == 0)
                    666:     ospf->external_origin |= (1 << DEFAULT_ROUTE);
                    667:   else
                    668:     thread_add_timer (master, ospf_default_originate_timer, ospf, 1);
                    669: 
                    670:   ospf_asbr_status_update (ospf, ++ospf->redistribute);
                    671: 
                    672:   return CMD_SUCCESS;
                    673: }
                    674: 
                    675: int
                    676: ospf_redistribute_default_unset (struct ospf *ospf)
                    677: {
                    678:   if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
                    679:     return CMD_SUCCESS;
                    680: 
                    681:   ospf->default_originate = DEFAULT_ORIGINATE_NONE;
                    682:   ospf->dmetric[DEFAULT_ROUTE].type = -1;
                    683:   ospf->dmetric[DEFAULT_ROUTE].value = -1;
                    684: 
                    685:   zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
                    686: 
                    687:   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    688:     zlog_debug ("Redistribute[DEFAULT]: Stop");
                    689: 
                    690:   ospf_asbr_status_update (ospf, --ospf->redistribute);
                    691: 
                    692:   return CMD_SUCCESS;
                    693: }
                    694: 
                    695: static int
                    696: ospf_external_lsa_originate_check (struct ospf *ospf,
                    697:                                    struct external_info *ei)
                    698: {
                    699:   /* If prefix is multicast, then do not originate LSA. */
                    700:   if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
                    701:     {
                    702:       zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
                    703:                  "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
                    704:       return 0;
                    705:     }
                    706: 
                    707:   /* Take care of default-originate. */
                    708:   if (is_prefix_default (&ei->p))
                    709:     if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
                    710:       {
                    711:         zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "
                    712:                    "for default");
                    713:         return 0;
                    714:       }
                    715: 
                    716:   return 1;
                    717: }
                    718: 
                    719: /* If connected prefix is OSPF enable interface, then do not announce. */
                    720: int
                    721: ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei)
                    722: {
                    723:   struct listnode *node;
                    724:   struct ospf_interface *oi;
                    725: 
                    726: 
                    727:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
                    728:       if (prefix_match (oi->address, (struct prefix *) &ei->p))
                    729:           return 0;
                    730:   return 1;
                    731: }
                    732: 
                    733: /* return 1 if external LSA must be originated, 0 otherwise */
                    734: int
                    735: ospf_redistribute_check (struct ospf *ospf,
                    736:                          struct external_info *ei, int *changed)
                    737: {
                    738:   struct route_map_set_values save_values;
                    739:   struct prefix_ipv4 *p = &ei->p;
                    740:   u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
                    741: 
                    742:   if (changed)
                    743:     *changed = 0;
                    744: 
                    745:   if (!ospf_external_lsa_originate_check (ospf, ei))
                    746:     return 0;
                    747: 
                    748:   /* Take care connected route. */
                    749:   if (type == ZEBRA_ROUTE_CONNECT &&
                    750:       !ospf_distribute_check_connected (ospf, ei))
                    751:     return 0;
                    752: 
                    753:   if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
                    754:     /* distirbute-list exists, but access-list may not? */
                    755:     if (DISTRIBUTE_LIST (ospf, type))
                    756:       if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
                    757:         {
                    758:           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    759:             zlog_debug ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
                    760:                        ospf_redist_string(type),
                    761:                        inet_ntoa (p->prefix), p->prefixlen);
                    762:           return 0;
                    763:         }
                    764: 
                    765:   save_values = ei->route_map_set;
                    766:   ospf_reset_route_map_set_values (&ei->route_map_set);
                    767: 
                    768:   /* apply route-map if needed */
                    769:   if (ROUTEMAP_NAME (ospf, type))
                    770:     {
                    771:       int ret;
                    772: 
                    773:       ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
                    774:                              RMAP_OSPF, ei);
                    775: 
                    776:       if (ret == RMAP_DENYMATCH)
                    777:         {
                    778:           ei->route_map_set = save_values;
                    779:           if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
                    780:             zlog_debug ("Redistribute[%s]: %s/%d filtered by route-map.",
                    781:                        ospf_redist_string(type),
                    782:                        inet_ntoa (p->prefix), p->prefixlen);
                    783:           return 0;
                    784:         }
                    785: 
                    786:       /* check if 'route-map set' changed something */
                    787:       if (changed)
                    788:         *changed = !ospf_route_map_set_compare (&ei->route_map_set,
                    789:                                                 &save_values);
                    790:     }
                    791: 
                    792:   return 1;
                    793: }
                    794: 
                    795: /* OSPF route-map set for redistribution */
                    796: void
                    797: ospf_routemap_set (struct ospf *ospf, int type, const char *name)
                    798: {
                    799:   if (ROUTEMAP_NAME (ospf, type))
                    800:     free (ROUTEMAP_NAME (ospf, type));
                    801: 
                    802:   ROUTEMAP_NAME (ospf, type) = strdup (name);
                    803:   ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
                    804: }
                    805: 
                    806: void
                    807: ospf_routemap_unset (struct ospf *ospf, int type)
                    808: {
                    809:   if (ROUTEMAP_NAME (ospf, type))
                    810:     free (ROUTEMAP_NAME (ospf, type));
                    811: 
                    812:   ROUTEMAP_NAME (ospf, type) = NULL;
                    813:   ROUTEMAP (ospf, type) = NULL;
                    814: }
                    815: 
                    816: /* Zebra route add and delete treatment. */
                    817: static int
                    818: ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
                    819:                       zebra_size_t length)
                    820: {
                    821:   struct stream *s;
                    822:   struct zapi_ipv4 api;
                    823:   unsigned long ifindex;
                    824:   struct in_addr nexthop;
                    825:   struct prefix_ipv4 p;
                    826:   struct external_info *ei;
                    827:   struct ospf *ospf;
                    828: 
                    829:   s = zclient->ibuf;
                    830:   ifindex = 0;
                    831:   nexthop.s_addr = 0;
                    832: 
                    833:   /* Type, flags, message. */
                    834:   api.type = stream_getc (s);
                    835:   api.flags = stream_getc (s);
                    836:   api.message = stream_getc (s);
                    837: 
                    838:   /* IPv4 prefix. */
                    839:   memset (&p, 0, sizeof (struct prefix_ipv4));
                    840:   p.family = AF_INET;
                    841:   p.prefixlen = stream_getc (s);
                    842:   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
                    843: 
                    844:   if (IPV4_NET127(ntohl(p.prefix.s_addr)))
                    845:     return 0;
                    846: 
                    847:   /* Nexthop, ifindex, distance, metric. */
                    848:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
                    849:     {
                    850:       api.nexthop_num = stream_getc (s);
                    851:       nexthop.s_addr = stream_get_ipv4 (s);
                    852:     }
                    853:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
                    854:     {
                    855:       api.ifindex_num = stream_getc (s);
                    856:       /* XXX assert(api.ifindex_num == 1); */
                    857:       ifindex = stream_getl (s);
                    858:     }
                    859:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
                    860:     api.distance = stream_getc (s);
                    861:   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
                    862:     api.metric = stream_getl (s);
                    863: 
                    864:   ospf = ospf_lookup ();
                    865:   if (ospf == NULL)
                    866:     return 0;
                    867: 
                    868:   if (command == ZEBRA_IPV4_ROUTE_ADD)
                    869:     {
                    870:       /* XXX|HACK|TODO|FIXME:
                    871:        * Maybe we should ignore reject/blackhole routes? Testing shows that
                    872:        * there is no problems though and this is only way to "summarize"
                    873:        * routes in ASBR at the moment. Maybe we need just a better generalised
                    874:        * solution for these types?
                    875:        *
                    876:        * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
                    877:        *     || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
                    878:        * return 0;
                    879:        */
                    880:         
                    881:       ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
                    882: 
                    883:       if (ospf->router_id.s_addr == 0)
                    884:         /* Set flags to generate AS-external-LSA originate event
                    885:            for each redistributed protocols later. */
                    886:         ospf->external_origin |= (1 << api.type);
                    887:       else
                    888:         {
                    889:           if (ei)
                    890:             {
                    891:               if (is_prefix_default (&p))
                    892:                 ospf_external_lsa_refresh_default (ospf);
                    893:               else
                    894:                 {
                    895:                   struct ospf_lsa *current;
                    896: 
                    897:                   current = ospf_external_info_find_lsa (ospf, &ei->p);
                    898:                   if (!current)
                    899:                     ospf_external_lsa_originate (ospf, ei);
                    900:                   else if (IS_LSA_MAXAGE (current))
                    901:                     ospf_external_lsa_refresh (ospf, current,
                    902:                                                ei, LSA_REFRESH_FORCE);
                    903:                   else
                    904:                     zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
                    905:                                inet_ntoa (p.prefix));
                    906:                 }
                    907:             }
                    908:         }
                    909:     }
                    910:   else                          /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
                    911:     {
                    912:       ospf_external_info_delete (api.type, p);
                    913:       if (is_prefix_default (&p))
                    914:         ospf_external_lsa_refresh_default (ospf);
                    915:       else
                    916:         ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */);
                    917:     }
                    918: 
                    919:   return 0;
                    920: }
                    921: 
                    922: 
                    923: int
                    924: ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name)
                    925: {
                    926:   /* Lookup access-list for distribute-list. */
                    927:   DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
                    928: 
                    929:   /* Clear previous distribute-name. */
                    930:   if (DISTRIBUTE_NAME (ospf, type))
                    931:     free (DISTRIBUTE_NAME (ospf, type));
                    932: 
                    933:   /* Set distribute-name. */
                    934:   DISTRIBUTE_NAME (ospf, type) = strdup (name);
                    935: 
                    936:   /* If access-list have been set, schedule update timer. */
                    937:   if (DISTRIBUTE_LIST (ospf, type))
                    938:     ospf_distribute_list_update (ospf, type);
                    939: 
                    940:   return CMD_SUCCESS;
                    941: }
                    942: 
                    943: int
                    944: ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
                    945: {
                    946:   /* Schedule update timer. */
                    947:   if (DISTRIBUTE_LIST (ospf, type))
                    948:     ospf_distribute_list_update (ospf, type);
                    949: 
                    950:   /* Unset distribute-list. */
                    951:   DISTRIBUTE_LIST (ospf, type) = NULL;
                    952: 
                    953:   /* Clear distribute-name. */
                    954:   if (DISTRIBUTE_NAME (ospf, type))
                    955:     free (DISTRIBUTE_NAME (ospf, type));
                    956: 
                    957:   DISTRIBUTE_NAME (ospf, type) = NULL;
                    958: 
                    959:   return CMD_SUCCESS;
                    960: }
                    961: 
                    962: /* distribute-list update timer. */
                    963: static int
                    964: ospf_distribute_list_update_timer (struct thread *thread)
                    965: {
                    966:   struct route_node *rn;
                    967:   struct external_info *ei;
                    968:   struct route_table *rt;
                    969:   struct ospf_lsa *lsa;
                    970:   int type, default_refresh = 0;
                    971:   struct ospf *ospf;
                    972: 
                    973:   ospf = ospf_lookup ();
                    974:   if (ospf == NULL)
                    975:     return 0;
                    976: 
                    977:   ospf->t_distribute_update = NULL;
                    978: 
                    979:   zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
                    980: 
                    981:   /* foreach all external info. */
                    982:   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
                    983:     {
                    984:       rt = EXTERNAL_INFO (type);
                    985:       if (!rt)
                    986:        continue;
                    987:       for (rn = route_top (rt); rn; rn = route_next (rn))
                    988:        if ((ei = rn->info) != NULL)
                    989:          {
                    990:            if (is_prefix_default (&ei->p))
                    991:              default_refresh = 1;
                    992:            else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
                    993:              ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
                    994:            else
                    995:              ospf_external_lsa_originate (ospf, ei);
                    996:          }
                    997:     }
                    998:   if (default_refresh)
                    999:     ospf_external_lsa_refresh_default (ospf);
                   1000:   return 0;
                   1001: }
                   1002: 
                   1003: #define OSPF_DISTRIBUTE_UPDATE_DELAY 5
                   1004: 
                   1005: /* Update distribute-list and set timer to apply access-list. */
                   1006: void
1.1.1.3 ! misho    1007: ospf_distribute_list_update (struct ospf *ospf, uintptr_t type)
1.1       misho    1008: {
                   1009:   struct route_table *rt;
                   1010: 
                   1011:   /* External info does not exist. */
                   1012:   if (!(rt = EXTERNAL_INFO (type)))
                   1013:     return;
                   1014: 
                   1015:   /* If exists previously invoked thread, then let it continue. */
                   1016:   if (ospf->t_distribute_update)
                   1017:     return;
                   1018: 
                   1019:   /* Set timer. */
                   1020:   ospf->t_distribute_update =
                   1021:     thread_add_timer (master, ospf_distribute_list_update_timer,
                   1022:                       (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
                   1023: }
                   1024: 
                   1025: /* If access-list is updated, apply some check. */
                   1026: static void
                   1027: ospf_filter_update (struct access_list *access)
                   1028: {
                   1029:   struct ospf *ospf;
                   1030:   int type;
                   1031:   int abr_inv = 0;
                   1032:   struct ospf_area *area;
                   1033:   struct listnode *node;
                   1034: 
                   1035:   /* If OSPF instatnce does not exist, return right now. */
                   1036:   ospf = ospf_lookup ();
                   1037:   if (ospf == NULL)
                   1038:     return;
                   1039: 
                   1040:   /* Update distribute-list, and apply filter. */
                   1041:   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
                   1042:     {
                   1043:       if (ROUTEMAP (ospf, type) != NULL)
                   1044:         {
                   1045:           /* if route-map is not NULL it may be using this access list */
                   1046:           ospf_distribute_list_update (ospf, type);
                   1047:           continue;
                   1048:         }
                   1049: 
                   1050:       /* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
                   1051:        * but no distribute list. */
                   1052:       if (type == ZEBRA_ROUTE_MAX)
                   1053:        break;
                   1054: 
                   1055:       if (DISTRIBUTE_NAME (ospf, type))
                   1056:         {
                   1057:           /* Keep old access-list for distribute-list. */
                   1058:           struct access_list *old = DISTRIBUTE_LIST (ospf, type);
                   1059: 
                   1060:           /* Update access-list for distribute-list. */
                   1061:           DISTRIBUTE_LIST (ospf, type) =
                   1062:             access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
                   1063: 
                   1064:           /* No update for this distribute type. */
                   1065:           if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
                   1066:             continue;
                   1067: 
                   1068:           /* Schedule distribute-list update timer. */
                   1069:           if (DISTRIBUTE_LIST (ospf, type) == NULL ||
                   1070:               strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
                   1071:             ospf_distribute_list_update (ospf, type);
                   1072:         }
                   1073:     }
                   1074: 
                   1075:   /* Update Area access-list. */
                   1076:   for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
                   1077:     {
                   1078:       if (EXPORT_NAME (area))
                   1079:         {
                   1080:           EXPORT_LIST (area) = NULL;
                   1081:           abr_inv++;
                   1082:         }
                   1083: 
                   1084:       if (IMPORT_NAME (area))
                   1085:         {
                   1086:           IMPORT_LIST (area) = NULL;
                   1087:           abr_inv++;
                   1088:         }
                   1089:     }
                   1090: 
                   1091:   /* Schedule ABR tasks -- this will be changed -- takada. */
                   1092:   if (IS_OSPF_ABR (ospf) && abr_inv)
                   1093:     ospf_schedule_abr_task (ospf);
                   1094: }
                   1095: 
                   1096: /* If prefix-list is updated, do some updates. */
                   1097: void
                   1098: ospf_prefix_list_update (struct prefix_list *plist)
                   1099: {
                   1100:   struct ospf *ospf;
                   1101:   int type;
                   1102:   int abr_inv = 0;
                   1103:   struct ospf_area *area;
                   1104:   struct listnode *node;
                   1105: 
                   1106:   /* If OSPF instatnce does not exist, return right now. */
                   1107:   ospf = ospf_lookup ();
                   1108:   if (ospf == NULL)
                   1109:     return;
                   1110: 
                   1111:   /* Update all route-maps which are used as redistribution filters.
                   1112:    * They might use prefix-list.
                   1113:    */
                   1114:   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
                   1115:     {
                   1116:       if (ROUTEMAP (ospf, type) != NULL)
                   1117:         {
                   1118:           /* If route-map is not NULL it may be using this prefix list */
                   1119:           ospf_distribute_list_update (ospf, type);
                   1120:           continue;
                   1121:         }
                   1122:     }
                   1123: 
                   1124:   /* Update area filter-lists. */
                   1125:   for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
                   1126:     {
                   1127:       /* Update filter-list in. */
                   1128:       if (PREFIX_NAME_IN (area))
                   1129:         if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0)
                   1130:           {
                   1131:             PREFIX_LIST_IN (area) =
                   1132:               prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area));
                   1133:             abr_inv++;
                   1134:           }
                   1135: 
                   1136:       /* Update filter-list out. */
                   1137:       if (PREFIX_NAME_OUT (area))
                   1138:         if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0)
                   1139:           {
                   1140:             PREFIX_LIST_IN (area) =
                   1141:               prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area));
                   1142:             abr_inv++;
                   1143:           }
                   1144:     }
                   1145: 
                   1146:   /* Schedule ABR task. */
                   1147:   if (IS_OSPF_ABR (ospf) && abr_inv)
                   1148:     ospf_schedule_abr_task (ospf);
                   1149: }
                   1150: 
                   1151: static struct ospf_distance *
                   1152: ospf_distance_new (void)
                   1153: {
                   1154:   return XCALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
                   1155: }
                   1156: 
                   1157: static void
                   1158: ospf_distance_free (struct ospf_distance *odistance)
                   1159: {
                   1160:   XFREE (MTYPE_OSPF_DISTANCE, odistance);
                   1161: }
                   1162: 
                   1163: int
                   1164: ospf_distance_set (struct vty *vty, struct ospf *ospf, 
                   1165:                    const char *distance_str,
                   1166:                    const char *ip_str, 
                   1167:                    const char *access_list_str)
                   1168: {
                   1169:   int ret;
                   1170:   struct prefix_ipv4 p;
                   1171:   u_char distance;
                   1172:   struct route_node *rn;
                   1173:   struct ospf_distance *odistance;
                   1174: 
                   1175:   ret = str2prefix_ipv4 (ip_str, &p);
                   1176:   if (ret == 0)
                   1177:     {
                   1178:       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
                   1179:       return CMD_WARNING;
                   1180:     }
                   1181: 
                   1182:   distance = atoi (distance_str);
                   1183: 
                   1184:   /* Get OSPF distance node. */
                   1185:   rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
                   1186:   if (rn->info)
                   1187:     {
                   1188:       odistance = rn->info;
                   1189:       route_unlock_node (rn);
                   1190:     }
                   1191:   else
                   1192:     {
                   1193:       odistance = ospf_distance_new ();
                   1194:       rn->info = odistance;
                   1195:     }
                   1196: 
                   1197:   /* Set distance value. */
                   1198:   odistance->distance = distance;
                   1199: 
                   1200:   /* Reset access-list configuration. */
                   1201:   if (odistance->access_list)
                   1202:     {
                   1203:       free (odistance->access_list);
                   1204:       odistance->access_list = NULL;
                   1205:     }
                   1206:   if (access_list_str)
                   1207:     odistance->access_list = strdup (access_list_str);
                   1208: 
                   1209:   return CMD_SUCCESS;
                   1210: }
                   1211: 
                   1212: int
                   1213: ospf_distance_unset (struct vty *vty, struct ospf *ospf, 
                   1214:                      const char *distance_str,
                   1215:                      const char *ip_str, char 
                   1216:                      const *access_list_str)
                   1217: {
                   1218:   int ret;
                   1219:   struct prefix_ipv4 p;
                   1220:   struct route_node *rn;
                   1221:   struct ospf_distance *odistance;
                   1222: 
                   1223:   ret = str2prefix_ipv4 (ip_str, &p);
                   1224:   if (ret == 0)
                   1225:     {
                   1226:       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
                   1227:       return CMD_WARNING;
                   1228:     }
                   1229: 
                   1230:   rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p);
                   1231:   if (!rn)
                   1232:     {
                   1233:       vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
                   1234:       return CMD_WARNING;
                   1235:     }
                   1236: 
                   1237:   odistance = rn->info;
                   1238: 
                   1239:   if (odistance->access_list)
                   1240:     free (odistance->access_list);
                   1241:   ospf_distance_free (odistance);
                   1242: 
                   1243:   rn->info = NULL;
                   1244:   route_unlock_node (rn);
                   1245:   route_unlock_node (rn);
                   1246: 
                   1247:   return CMD_SUCCESS;
                   1248: }
                   1249: 
                   1250: void
                   1251: ospf_distance_reset (struct ospf *ospf)
                   1252: {
                   1253:   struct route_node *rn;
                   1254:   struct ospf_distance *odistance;
                   1255: 
                   1256:   for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
                   1257:     if ((odistance = rn->info) != NULL)
                   1258:       {
                   1259:         if (odistance->access_list)
                   1260:           free (odistance->access_list);
                   1261:         ospf_distance_free (odistance);
                   1262:         rn->info = NULL;
                   1263:         route_unlock_node (rn);
                   1264:       }
                   1265: }
                   1266: 
                   1267: u_char
                   1268: ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
                   1269: {
                   1270:   struct ospf *ospf;
                   1271: 
                   1272:   ospf = ospf_lookup ();
                   1273:   if (ospf == NULL)
                   1274:     return 0;
                   1275: 
                   1276:   if (ospf->distance_intra)
                   1277:     if (or->path_type == OSPF_PATH_INTRA_AREA)
                   1278:       return ospf->distance_intra;
                   1279: 
                   1280:   if (ospf->distance_inter)
                   1281:     if (or->path_type == OSPF_PATH_INTER_AREA)
                   1282:       return ospf->distance_inter;
                   1283: 
                   1284:   if (ospf->distance_external)
                   1285:     if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
                   1286:         || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
                   1287:       return ospf->distance_external;
                   1288: 
                   1289:   if (ospf->distance_all)
                   1290:     return ospf->distance_all;
                   1291: 
                   1292:   return 0;
                   1293: }
                   1294: 
                   1295: void
                   1296: ospf_zebra_init ()
                   1297: {
                   1298:   /* Allocate zebra structure. */
                   1299:   zclient = zclient_new ();
                   1300:   zclient_init (zclient, ZEBRA_ROUTE_OSPF);
                   1301:   zclient->router_id_update = ospf_router_id_update_zebra;
                   1302:   zclient->interface_add = ospf_interface_add;
                   1303:   zclient->interface_delete = ospf_interface_delete;
                   1304:   zclient->interface_up = ospf_interface_state_up;
                   1305:   zclient->interface_down = ospf_interface_state_down;
                   1306:   zclient->interface_address_add = ospf_interface_address_add;
                   1307:   zclient->interface_address_delete = ospf_interface_address_delete;
                   1308:   zclient->ipv4_route_add = ospf_zebra_read_ipv4;
                   1309:   zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
                   1310: 
                   1311:   access_list_add_hook (ospf_filter_update);
                   1312:   access_list_delete_hook (ospf_filter_update);
                   1313:   prefix_list_add_hook (ospf_prefix_list_update);
                   1314:   prefix_list_delete_hook (ospf_prefix_list_update);
                   1315: }

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