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

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

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