ospf_zebra.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:27k
源码类别:

网络

开发平台:

Unix_Linux

  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. #include <zebra.h>
  23. #include "thread.h"
  24. #include "command.h"
  25. #include "network.h"
  26. #include "prefix.h"
  27. #include "routemap.h"
  28. #include "table.h"
  29. #include "stream.h"
  30. #include "memory.h"
  31. #include "zclient.h"
  32. #include "filter.h"
  33. #include "log.h"
  34. #include "ospfd/ospfd.h"
  35. #include "ospfd/ospf_interface.h"
  36. #include "ospfd/ospf_ism.h"
  37. #include "ospfd/ospf_asbr.h"
  38. #include "ospfd/ospf_asbr.h"
  39. #include "ospfd/ospf_abr.h"
  40. #include "ospfd/ospf_lsa.h"
  41. #include "ospfd/ospf_dump.h"
  42. #include "ospfd/ospf_route.h"
  43. #include "ospfd/ospf_zebra.h"
  44. #ifdef HAVE_SNMP
  45. #include "ospfd/ospf_snmp.h"
  46. #endif /* HAVE_SNMP */
  47. /* Zebra structure to hold current status. */
  48. struct zclient *zclient = NULL;
  49. /* For registering threads. */
  50. extern struct thread_master *master;
  51. /* Inteface addition message from zebra. */
  52. int
  53. ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
  54. {
  55.   struct interface *ifp;
  56.   struct ospf *ospf;
  57.   ifp = zebra_interface_add_read (zclient->ibuf);
  58.   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
  59.     zlog_info ("Zebra: interface add %s index %d flags %ld metric %d mtu %d",
  60.        ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
  61.   if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
  62.     {
  63.       SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
  64.       IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;
  65.       
  66.       if (if_is_broadcast (ifp))
  67. IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;
  68.       else if (if_is_pointopoint (ifp))
  69. IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_POINTOPOINT;
  70.       else if (if_is_loopback (ifp))
  71. IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_LOOPBACK;
  72.     }
  73.   ospf = ospf_lookup ();
  74.   if (ospf != NULL)
  75.     ospf_if_update (ospf);
  76. #ifdef HAVE_SNMP
  77.   ospf_snmp_if_update (ifp);
  78. #endif /* HAVE_SNMP */
  79.   return 0;
  80. }
  81. int
  82. ospf_interface_delete (int command, struct zclient *zclient,
  83.        zebra_size_t length)
  84. {
  85.   struct interface *ifp;
  86.   struct stream *s;
  87.   struct route_node *rn;
  88.   s = zclient->ibuf;  
  89.   /* zebra_interface_state_read() updates interface structure in iflist */
  90.   ifp = zebra_interface_state_read (s);
  91.   if (ifp == NULL)
  92.     return 0;
  93.   if (if_is_up (ifp))
  94.     zlog_warn ("Zebra: got delete of %s, but interface is still up",
  95.        ifp->name);
  96.   
  97.   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
  98.     zlog_info ("Zebra: interface delete %s index %d flags %ld metric %d mtu %d",
  99.        ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);  
  100. #ifdef HAVE_SNMP
  101.   ospf_snmp_if_delete (ifp);
  102. #endif /* HAVE_SNMP */
  103.   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  104.     if (rn->info)
  105.       ospf_if_free ((struct ospf_interface *) rn->info);
  106.   for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
  107.     if (rn->info)
  108.       ospf_del_if_params (rn->info);
  109.   
  110.   if_delete (ifp);
  111.   return 0;
  112. }
  113. struct interface *
  114. zebra_interface_if_lookup (struct stream *s)
  115. {
  116.   struct interface *ifp;
  117.   u_char ifname_tmp[INTERFACE_NAMSIZ];
  118.   /* Read interface name. */
  119.   stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
  120.   /* Lookup this by interface index. */
  121.   ifp = if_lookup_by_name (ifname_tmp);
  122.   /* If such interface does not exist, indicate an error */
  123.   if (!ifp)
  124.     return NULL;
  125.   return ifp;
  126. }
  127. void
  128. zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
  129. {
  130.   /* Read interface's index. */
  131.   ifp->ifindex = stream_getl (s);
  132.   /* Read interface's value. */
  133.   ifp->flags = stream_getl (s);
  134.   ifp->metric = stream_getl (s);
  135.   ifp->mtu = stream_getl (s);
  136.   ifp->bandwidth = stream_getl (s);
  137. }
  138. int
  139. ospf_interface_state_up (int command, struct zclient *zclient,
  140.  zebra_size_t length)
  141. {
  142.   struct interface *ifp;
  143.   struct interface if_tmp;
  144.   struct ospf_interface *oi;
  145.   struct route_node *rn;
  146.   
  147.   ifp = zebra_interface_if_lookup (zclient->ibuf);
  148.   if (ifp == NULL)
  149.     return 0;
  150.   /* Interface is already up. */
  151.   if (if_is_up (ifp))
  152.     {
  153.       /* Temporarily keep ifp values. */
  154.       memcpy (&if_tmp, ifp, sizeof (struct interface));
  155.       zebra_interface_if_set_value (zclient->ibuf, ifp);
  156.       if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
  157. zlog_info ("Zebra: Interface[%s] state update.", ifp->name);
  158.       if (if_tmp.bandwidth != ifp->bandwidth)
  159. {
  160.   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
  161.     zlog_info ("Zebra: Interface[%s] bandwidth change %d -> %d.",
  162.        ifp->name, if_tmp.bandwidth, ifp->bandwidth);
  163.   ospf_if_recalculate_output_cost (ifp);
  164. }
  165.       return 0;
  166.     }
  167.   
  168.   zebra_interface_if_set_value (zclient->ibuf, ifp);
  169.   
  170.   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
  171.     zlog_info ("Zebra: Interface[%s] state change to up.", ifp->name);
  172.   
  173.   for (rn = route_top (IF_OIFS (ifp));rn; rn = route_next (rn))
  174.     {
  175.       if ( (oi = rn->info) == NULL)
  176. continue;
  177.       
  178.       ospf_if_up (oi);
  179.     }
  180.   
  181.   return 0;
  182. }
  183. int
  184. ospf_interface_state_down (int command, struct zclient *zclient,
  185.    zebra_size_t length)
  186. {
  187.   struct interface *ifp;
  188.   struct ospf_interface *oi;
  189.   struct route_node *node;
  190.   ifp = zebra_interface_state_read (zclient->ibuf);
  191.   if (ifp == NULL)
  192.     return 0;
  193.   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
  194.     zlog_info ("Zebra: Interface[%s] state change to down.", ifp->name);
  195.   for (node = route_top (IF_OIFS (ifp));node; node = route_next (node))
  196.     {
  197.       if ( (oi = node->info) == NULL)
  198. continue;
  199.       ospf_if_down (oi);
  200.     }
  201.   return 0;
  202. }
  203. int
  204. ospf_interface_address_add (int command, struct zclient *zclient,
  205.     zebra_size_t length)
  206. {
  207.   struct ospf *ospf;
  208.   struct connected *c;
  209.   c = zebra_interface_address_add_read (zclient->ibuf);
  210.   if (c == NULL)
  211.     return 0;
  212.   ospf = ospf_lookup ();
  213.   if (ospf != NULL)
  214.     ospf_if_update (ospf);
  215. #ifdef HAVE_SNMP
  216.   ospf_snmp_if_update (c->ifp);
  217. #endif /* HAVE_SNMP */
  218.   return 0;
  219. }
  220. int
  221. ospf_interface_address_delete (int command, struct zclient *zclient,
  222.        zebra_size_t length)
  223. {
  224.   struct ospf *ospf;
  225.   struct connected *c;
  226.   struct interface *ifp;
  227.   struct ospf_interface *oi;
  228.   struct route_node *rn;
  229.   struct prefix p;
  230.   c = zebra_interface_address_delete_read (zclient->ibuf);
  231.   if (c == NULL)
  232.     return 0;
  233.   ifp = c->ifp;
  234.   p = *c->address;
  235.   p.prefixlen = IPV4_MAX_PREFIXLEN;
  236.   rn = route_node_lookup (IF_OIFS (ifp), &p);
  237.   if (! rn)
  238.     return 0;
  239.   assert (rn->info);
  240.   oi = rn->info;
  241.   
  242.   /* Call interface hook functions to clean up */
  243.   ospf_if_free (oi);
  244.   
  245. #ifdef HAVE_SNMP
  246.   ospf_snmp_if_update (c->ifp);
  247. #endif /* HAVE_SNMP */
  248.   connected_free (c);
  249.   ospf = ospf_lookup ();
  250.   if (ospf != NULL)
  251.     ospf_if_update (ospf);
  252.   return 0;
  253. }
  254. void
  255. ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
  256. {
  257.   u_char message;
  258.   u_char distance;
  259.   u_char flags;
  260.   int psize;
  261.   struct stream *s;
  262.   struct ospf_path *path;
  263.   listnode node;
  264.   if (zclient->redist[ZEBRA_ROUTE_OSPF])
  265.     {
  266.       message = 0;
  267.       flags = 0;
  268.       /* OSPF pass nexthop and metric */
  269.       SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
  270.       SET_FLAG (message, ZAPI_MESSAGE_METRIC);
  271.       /* Distance value. */
  272.       distance = ospf_distance_apply (p, or);
  273.       if (distance)
  274. SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
  275.       /* Make packet. */
  276.       s = zclient->obuf;
  277.       stream_reset (s);
  278.       /* Length place holder. */
  279.       stream_putw (s, 0);
  280.       /* Put command, type, flags, message. */
  281.       stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
  282.       stream_putc (s, ZEBRA_ROUTE_OSPF);
  283.       stream_putc (s, flags);
  284.       stream_putc (s, message);
  285.   
  286.       /* Put prefix information. */
  287.       psize = PSIZE (p->prefixlen);
  288.       stream_putc (s, p->prefixlen);
  289.       stream_write (s, (u_char *)&p->prefix, psize);
  290.       /* Nexthop count. */
  291.       stream_putc (s, or->path->count);
  292.       /* Nexthop, ifindex, distance and metric information. */
  293.       for (node = listhead (or->path); node; nextnode (node))
  294. {
  295.   path = getdata (node);
  296.   if (path->nexthop.s_addr != INADDR_ANY)
  297.     {
  298.       stream_putc (s, ZEBRA_NEXTHOP_IPV4);
  299.       stream_put_in_addr (s, &path->nexthop);
  300.     }
  301.   else
  302.     {
  303.       stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
  304.       if (path->oi)
  305. stream_putl (s, path->oi->ifp->ifindex);
  306.       else
  307. stream_putl (s, 0);
  308.     }
  309. }
  310.       if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
  311. stream_putc (s, distance);
  312.       if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
  313. {
  314.   if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
  315.     stream_putl (s, or->cost + or->u.ext.type2_cost);
  316.   else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
  317.     stream_putl (s, or->u.ext.type2_cost);
  318.   else
  319.     stream_putl (s, or->cost);
  320. }
  321.       stream_putw_at (s, 0, stream_get_endp (s));
  322.       writen (zclient->sock, s->data, stream_get_endp (s));
  323.     }
  324. }
  325. void
  326. ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
  327. {
  328.   struct zapi_ipv4 api;
  329.   if (zclient->redist[ZEBRA_ROUTE_OSPF])
  330.     {
  331.       api.type = ZEBRA_ROUTE_OSPF;
  332.       api.flags = 0;
  333.       api.message = 0;
  334.       zapi_ipv4_delete (zclient, p, &api);
  335.     }
  336. }
  337. void
  338. ospf_zebra_add_discard (struct prefix_ipv4 *p)
  339. {
  340.   struct zapi_ipv4 api;
  341.   if (zclient->redist[ZEBRA_ROUTE_OSPF])
  342.     {
  343.       api.type = ZEBRA_ROUTE_OSPF;
  344.       api.flags = ZEBRA_FLAG_BLACKHOLE;
  345.       api.message = 0;
  346.       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  347.       api.nexthop_num = 0;
  348.       api.ifindex_num = 0;
  349.       zapi_ipv4_add (zclient, p, &api);
  350.     }
  351. }
  352. void
  353. ospf_zebra_delete_discard (struct prefix_ipv4 *p)
  354. {
  355.   struct zapi_ipv4 api;
  356.   if (zclient->redist[ZEBRA_ROUTE_OSPF])
  357.     {
  358.       api.type = ZEBRA_ROUTE_OSPF;
  359.       api.flags = ZEBRA_FLAG_BLACKHOLE;
  360.       api.message = 0;
  361.       SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  362.       api.nexthop_num = 0;
  363.       api.ifindex_num = 0;
  364.       zapi_ipv4_delete (zclient, p, &api);
  365.     }
  366. }
  367. int
  368. ospf_is_type_redistributed (int type)
  369. {
  370.   return (DEFAULT_ROUTE_TYPE (type)) ?
  371.     zclient->default_information : zclient->redist[type];
  372. }
  373. int
  374. ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
  375. {
  376.   int force = 0;
  377.   
  378.   if (ospf_is_type_redistributed (type))
  379.     {
  380.       if (mtype != ospf->dmetric[type].type)
  381. {
  382.   ospf->dmetric[type].type = mtype;
  383.   force = LSA_REFRESH_FORCE;
  384. }
  385.       if (mvalue != ospf->dmetric[type].value)
  386. {
  387.   ospf->dmetric[type].value = mvalue;
  388.   force = LSA_REFRESH_FORCE;
  389. }
  390.   
  391.       ospf_external_lsa_refresh_type (ospf, type, force);
  392.       
  393.       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
  394. zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
  395.    LOOKUP (ospf_redistributed_proto, type),
  396.    metric_type (ospf, type), metric_value (ospf, type));
  397.       
  398.       return CMD_SUCCESS;
  399.     }
  400.   ospf->dmetric[type].type = mtype;
  401.   ospf->dmetric[type].value = mvalue;
  402.   zclient_redistribute_set (zclient, type);
  403.   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
  404.     zlog_info ("Redistribute[%s]: Start  Type[%d], Metric[%d]",
  405.        LOOKUP (ospf_redistributed_proto, type),
  406.        metric_type (ospf, type), metric_value (ospf, type));
  407.   
  408.   ospf_asbr_status_update (ospf, ++ospf->redistribute);
  409.   return CMD_SUCCESS;
  410. }
  411. int
  412. ospf_redistribute_unset (struct ospf *ospf, int type)
  413. {
  414.   if (type == zclient->redist_default)
  415.     return CMD_SUCCESS;
  416.   if (! ospf_is_type_redistributed (type))
  417.     return CMD_SUCCESS;
  418.   zclient_redistribute_unset (zclient, type);
  419.   
  420.   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
  421.     zlog_info ("Redistribute[%s]: Stop",
  422.        LOOKUP (ospf_redistributed_proto, type));
  423.   ospf->dmetric[type].type = -1;
  424.   ospf->dmetric[type].value = -1;
  425.   /* Remove the routes from OSPF table. */
  426.   ospf_redistribute_withdraw (type);
  427.   ospf_asbr_status_update (ospf, --ospf->redistribute);
  428.   return CMD_SUCCESS;
  429. }
  430. int
  431. ospf_redistribute_default_set (struct ospf *ospf, int originate,
  432.        int mtype, int mvalue)
  433. {
  434.   int force = 0;
  435.   if (ospf_is_type_redistributed (DEFAULT_ROUTE))
  436.     {
  437.       if (mtype != ospf->dmetric[DEFAULT_ROUTE].type)
  438. {
  439.   ospf->dmetric[DEFAULT_ROUTE].type = mtype;
  440.   force = 1;
  441. }
  442.       if (mvalue != ospf->dmetric[DEFAULT_ROUTE].value)
  443. {
  444.   force = 1;
  445.   ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
  446. }
  447.       
  448.       ospf_external_lsa_refresh_default (ospf);
  449.       
  450.       if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
  451. zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",
  452.    LOOKUP (ospf_redistributed_proto, DEFAULT_ROUTE),
  453.    metric_type (ospf, DEFAULT_ROUTE),
  454.    metric_value (ospf, DEFAULT_ROUTE));
  455.       return CMD_SUCCESS;
  456.     }
  457.   ospf->default_originate = originate;
  458.   ospf->dmetric[DEFAULT_ROUTE].type = mtype;
  459.   ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
  460.   zclient_redistribute_default_set (zclient);
  461.   
  462.   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
  463.     zlog_info ("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",
  464.        metric_type (ospf, DEFAULT_ROUTE),
  465.        metric_value (ospf, DEFAULT_ROUTE));
  466.   if (ospf->router_id.s_addr == 0)
  467.     ospf->external_origin |= (1 << DEFAULT_ROUTE);
  468.   else
  469.     thread_add_timer (master, ospf_default_originate_timer,
  470.       &ospf->default_originate, 1);
  471.   ospf_asbr_status_update (ospf, ++ospf->redistribute);
  472.   return CMD_SUCCESS;
  473. }
  474. int
  475. ospf_redistribute_default_unset (struct ospf *ospf)
  476. {
  477.   if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
  478.     return CMD_SUCCESS;
  479.   ospf->default_originate = DEFAULT_ORIGINATE_NONE;
  480.   ospf->dmetric[DEFAULT_ROUTE].type = -1;
  481.   ospf->dmetric[DEFAULT_ROUTE].value = -1;
  482.   zclient_redistribute_default_unset (zclient);
  483.   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
  484.     zlog_info ("Redistribute[DEFAULT]: Stop");
  485.   
  486.   ospf_asbr_status_update (ospf, --ospf->redistribute);
  487.   return CMD_SUCCESS;
  488. }
  489. int
  490. ospf_external_lsa_originate_check (struct ospf *ospf,
  491.    struct external_info *ei)
  492. {
  493.   /* If prefix is multicast, then do not originate LSA. */
  494.   if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
  495.     {
  496.       zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
  497.  "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
  498.       return 0;
  499.     }
  500.   /* Take care of default-originate. */
  501.   if (is_prefix_default (&ei->p))
  502.     if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
  503.       {
  504. zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA "
  505.    "for default");
  506. return 0;
  507.       }
  508.   return 1;
  509. }
  510. /* If connected prefix is OSPF enable interface, then do not announce. */
  511. int
  512. ospf_distribute_check_connected (struct ospf *ospf,
  513.  struct external_info *ei)
  514. {
  515.   struct route_node *rn;
  516.   for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
  517.     if (rn->info != NULL)
  518.       if (prefix_match (&rn->p, (struct prefix *)&ei->p))
  519. {
  520.   route_unlock_node (rn);
  521.   return 0;
  522. }
  523.   return 1;
  524. }
  525. /* return 1 if external LSA must be originated, 0 otherwise */
  526. int
  527. ospf_redistribute_check (struct ospf *ospf,
  528.  struct external_info *ei, int *changed)
  529. {
  530.   struct route_map_set_values save_values;
  531.   struct prefix_ipv4 *p = &ei->p;
  532.   u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
  533.   
  534.   if (changed)
  535.     *changed = 0;
  536.   if (!ospf_external_lsa_originate_check (ospf, ei))
  537.     return 0;
  538.   /* Take care connected route. */
  539.   if (type == ZEBRA_ROUTE_CONNECT &&
  540.       !ospf_distribute_check_connected (ospf, ei))
  541.     return 0;
  542.   if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
  543.     /* distirbute-list exists, but access-list may not? */
  544.     if (DISTRIBUTE_LIST (ospf, type))
  545.       if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
  546. {
  547.   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
  548.     zlog_info ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
  549.        LOOKUP (ospf_redistributed_proto, type),
  550.        inet_ntoa (p->prefix), p->prefixlen);
  551.   return 0;
  552. }
  553.   save_values = ei->route_map_set;
  554.   ospf_reset_route_map_set_values (&ei->route_map_set);
  555.   
  556.   /* apply route-map if needed */
  557.   if (ROUTEMAP_NAME (ospf, type))
  558.     {
  559.       int ret;
  560.       ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *)p,
  561.      RMAP_OSPF, ei);
  562.       if (ret == RMAP_DENYMATCH)
  563. {
  564.   ei->route_map_set = save_values;
  565.   if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
  566.     zlog_info ("Redistribute[%s]: %s/%d filtered by route-map.",
  567.        LOOKUP (ospf_redistributed_proto, type),
  568.        inet_ntoa (p->prefix), p->prefixlen);
  569.   return 0;
  570. }
  571.       
  572.       /* check if 'route-map set' changed something */
  573.       if (changed)
  574. *changed = !ospf_route_map_set_compare (&ei->route_map_set,
  575. &save_values);
  576.     }
  577.   return 1;
  578. }
  579. /* OSPF route-map set for redistribution */
  580. void
  581. ospf_routemap_set (struct ospf *ospf, int type, char *name)
  582. {
  583.   if (ROUTEMAP_NAME (ospf, type))
  584.     free (ROUTEMAP_NAME (ospf, type));
  585.   ROUTEMAP_NAME (ospf, type) = strdup (name);
  586.   ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
  587. }
  588. void
  589. ospf_routemap_unset (struct ospf *ospf, int type)
  590. {
  591.   if (ROUTEMAP_NAME (ospf, type))
  592.     free (ROUTEMAP_NAME (ospf, type));
  593.   ROUTEMAP_NAME (ospf, type) = NULL;
  594.   ROUTEMAP (ospf, type) = NULL;
  595. }
  596. /* Zebra route add and delete treatment. */
  597. int
  598. ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
  599.       zebra_size_t length)
  600. {
  601.   struct stream *s;
  602.   struct zapi_ipv4 api;
  603.   unsigned long ifindex;
  604.   struct in_addr nexthop;
  605.   struct prefix_ipv4 p;
  606.   struct external_info *ei;
  607.   struct ospf *ospf;
  608.   s = zclient->ibuf;
  609.   ifindex = 0;
  610.   nexthop.s_addr = 0;
  611.   /* Type, flags, message. */
  612.   api.type = stream_getc (s);
  613.   api.flags = stream_getc (s);
  614.   api.message = stream_getc (s);
  615.   /* IPv4 prefix. */
  616.   memset (&p, 0, sizeof (struct prefix_ipv4));
  617.   p.family = AF_INET;
  618.   p.prefixlen = stream_getc (s);
  619.   stream_get (&p.prefix, s, PSIZE (p.prefixlen));
  620.   /* Nexthop, ifindex, distance, metric. */
  621.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  622.     {
  623.       api.nexthop_num = stream_getc (s);
  624.       nexthop.s_addr = stream_get_ipv4 (s);
  625.     }
  626.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  627.     {
  628.       api.ifindex_num = stream_getc (s);
  629.       ifindex = stream_getl (s);
  630.     }
  631.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  632.     api.distance = stream_getc (s);
  633.   if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  634.     api.metric = stream_getl (s);
  635.   ospf = ospf_lookup ();
  636.   if (ospf == NULL)
  637.     return 0;
  638.   if (command == ZEBRA_IPV4_ROUTE_ADD)
  639.     {
  640.       ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
  641.       if (ospf->router_id.s_addr == 0)
  642. /* Set flags to generate AS-external-LSA originate event
  643.    for each redistributed protocols later. */
  644. ospf->external_origin |= (1 << api.type);
  645.       else
  646. {
  647.   if (ei)
  648.     {
  649.       if (is_prefix_default (&p))
  650. ospf_external_lsa_refresh_default (ospf);
  651.       else
  652. {
  653.   struct ospf_lsa *current;
  654.   current = ospf_external_info_find_lsa (ospf, &ei->p);
  655.   if (!current)
  656.     ospf_external_lsa_originate (ospf, ei);
  657.   else if (IS_LSA_MAXAGE (current))
  658.     ospf_external_lsa_refresh (ospf, current,
  659.        ei, LSA_REFRESH_FORCE);
  660.   else
  661.     zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
  662.        inet_ntoa (p.prefix));
  663. }
  664.     }
  665. }
  666.     }
  667.   else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
  668.     {
  669.       ospf_external_info_delete (api.type, p);
  670.       if ( !is_prefix_default (&p))
  671. ospf_external_lsa_flush (ospf, api.type, &p, ifindex, nexthop);
  672.       else
  673. ospf_external_lsa_refresh_default (ospf);
  674.     }
  675.   return 0;
  676. }
  677. int
  678. ospf_distribute_list_out_set (struct ospf *ospf, int type, char *name)
  679. {
  680.   /* Lookup access-list for distribute-list. */
  681.   DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
  682.   /* Clear previous distribute-name. */
  683.   if (DISTRIBUTE_NAME (ospf, type))
  684.     free (DISTRIBUTE_NAME (ospf, type));
  685.   /* Set distribute-name. */
  686.   DISTRIBUTE_NAME (ospf, type) = strdup (name);
  687.   /* If access-list have been set, schedule update timer. */
  688.   if (DISTRIBUTE_LIST (ospf, type))
  689.     ospf_distribute_list_update (ospf, type);
  690.   return CMD_SUCCESS;
  691. }
  692. int
  693. ospf_distribute_list_out_unset (struct ospf *ospf, int type, char *name)
  694. {
  695.   /* Schedule update timer. */
  696.   if (DISTRIBUTE_LIST (ospf, type))
  697.     ospf_distribute_list_update (ospf, type);
  698.   /* Unset distribute-list. */
  699.   DISTRIBUTE_LIST (ospf, type) = NULL;
  700.   /* Clear distribute-name. */
  701.   if (DISTRIBUTE_NAME (ospf, type))
  702.     free (DISTRIBUTE_NAME (ospf, type));
  703.   
  704.   DISTRIBUTE_NAME (ospf, type) = NULL;
  705.   return CMD_SUCCESS;
  706. }
  707. /* distribute-list update timer. */
  708. int
  709. ospf_distribute_list_update_timer (struct thread *thread)
  710. {
  711.   struct route_node *rn;
  712.   struct external_info *ei;
  713.   struct route_table *rt;
  714.   struct ospf_lsa *lsa;
  715.   u_char type;
  716.   struct ospf *ospf;
  717.   type = (int) THREAD_ARG (thread);
  718.   rt = EXTERNAL_INFO (type);
  719.   ospf = ospf_lookup ();
  720.   if (ospf == NULL)
  721.     return 0;
  722.   ospf->t_distribute_update = NULL;
  723.   zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
  724.   /* foreach all external info. */
  725.   if (rt)
  726.     for (rn = route_top (rt); rn; rn = route_next (rn))
  727.       if ((ei = rn->info) != NULL)
  728. {
  729.   if (is_prefix_default (&ei->p))
  730.     ospf_external_lsa_refresh_default (ospf);
  731.   else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
  732.     ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
  733.   else
  734.     ospf_external_lsa_originate (ospf, ei);
  735. }
  736.   return 0;
  737. }
  738. #define OSPF_DISTRIBUTE_UPDATE_DELAY 5
  739. /* Update distribute-list and set timer to apply access-list. */
  740. void
  741. ospf_distribute_list_update (struct ospf *ospf, int type)
  742. {
  743.   struct route_table *rt;
  744.   
  745.   /* External info does not exist. */
  746.   if (!(rt = EXTERNAL_INFO (type)))
  747.     return;
  748.   /* If exists previously invoked thread, then cancel it. */
  749.   if (ospf->t_distribute_update)
  750.     OSPF_TIMER_OFF (ospf->t_distribute_update);
  751.   /* Set timer. */
  752.   ospf->t_distribute_update =
  753.     thread_add_timer (master, ospf_distribute_list_update_timer,
  754.       (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
  755. }
  756. /* If access-list is updated, apply some check. */
  757. void
  758. ospf_filter_update (struct access_list *access)
  759. {
  760.   struct ospf *ospf;
  761.   int type;
  762.   int abr_inv = 0;
  763.   struct ospf_area *area;
  764.   listnode node;
  765.   /* If OSPF instatnce does not exist, return right now. */
  766.   ospf = ospf_lookup ();
  767.   if (ospf == NULL)
  768.     return;
  769.   /* Update distribute-list, and apply filter. */
  770.   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
  771.     {
  772.       if (ROUTEMAP (ospf, type) != NULL)
  773. {
  774.   /* if route-map is not NULL it may be using this access list */
  775.   ospf_distribute_list_update (ospf, type);
  776.   continue;
  777. }
  778.       
  779.       if (DISTRIBUTE_NAME (ospf, type))
  780. {
  781.   /* Keep old access-list for distribute-list. */
  782.   struct access_list *old = DISTRIBUTE_LIST (ospf, type);
  783.   
  784.   /* Update access-list for distribute-list. */
  785.   DISTRIBUTE_LIST (ospf, type) =
  786.     access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
  787.   
  788.   /* No update for this distribute type. */
  789.   if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
  790.     continue;
  791.   
  792.   /* Schedule distribute-list update timer. */
  793.   if (DISTRIBUTE_LIST (ospf, type) == NULL ||
  794.       strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
  795.     ospf_distribute_list_update (ospf, type);
  796. }
  797.     }
  798.   /* Update Area access-list. */
  799.   for (node = listhead (ospf->areas); node; nextnode (node))
  800.     if ((area = getdata (node)) != NULL)
  801.       {
  802. if (EXPORT_NAME (area))
  803.   {
  804.     EXPORT_LIST (area) = NULL;
  805.     abr_inv++;
  806.   }
  807. if (IMPORT_NAME (area))
  808.   {
  809.     IMPORT_LIST (area) = NULL;
  810.     abr_inv++;
  811.   }
  812.       }
  813.   /* Schedule ABR tasks -- this will be changed -- takada. */
  814.   if (IS_OSPF_ABR (ospf) && abr_inv)
  815.     ospf_schedule_abr_task (ospf);
  816. }
  817. struct ospf_distance *
  818. ospf_distance_new ()
  819. {
  820.   struct ospf_distance *new;
  821.   new = XMALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
  822.   memset (new, 0, sizeof (struct ospf_distance));
  823.   return new;
  824. }
  825. void
  826. ospf_distance_free (struct ospf_distance *odistance)
  827. {
  828.   XFREE (MTYPE_OSPF_DISTANCE, odistance);
  829. }
  830. int
  831. ospf_distance_set (struct vty *vty, struct ospf *ospf, char *distance_str,
  832.    char *ip_str, char *access_list_str)
  833. {
  834.   int ret;
  835.   struct prefix_ipv4 p;
  836.   u_char distance;
  837.   struct route_node *rn;
  838.   struct ospf_distance *odistance;
  839.   ret = str2prefix_ipv4 (ip_str, &p);
  840.   if (ret == 0)
  841.     {
  842.       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
  843.       return CMD_WARNING;
  844.     }
  845.   distance = atoi (distance_str);
  846.   /* Get OSPF distance node. */
  847.   rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
  848.   if (rn->info)
  849.     {
  850.       odistance = rn->info;
  851.       route_unlock_node (rn);
  852.     }
  853.   else
  854.     {
  855.       odistance = ospf_distance_new ();
  856.       rn->info = odistance;
  857.     }
  858.   /* Set distance value. */
  859.   odistance->distance = distance;
  860.   /* Reset access-list configuration. */
  861.   if (odistance->access_list)
  862.     {
  863.       free (odistance->access_list);
  864.       odistance->access_list = NULL;
  865.     }
  866.   if (access_list_str)
  867.     odistance->access_list = strdup (access_list_str);
  868.   return CMD_SUCCESS;
  869. }
  870. int
  871. ospf_distance_unset (struct vty *vty, struct ospf *ospf, char *distance_str,
  872.      char *ip_str, char *access_list_str)
  873. {
  874.   int ret;
  875.   struct prefix_ipv4 p;
  876.   u_char distance;
  877.   struct route_node *rn;
  878.   struct ospf_distance *odistance;
  879.   ret = str2prefix_ipv4 (ip_str, &p);
  880.   if (ret == 0)
  881.     {
  882.       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
  883.       return CMD_WARNING;
  884.     }
  885.   distance = atoi (distance_str);
  886.   rn = route_node_lookup (ospf->distance_table, (struct prefix *)&p);
  887.   if (! rn)
  888.     {
  889.       vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
  890.       return CMD_WARNING;
  891.     }
  892.   odistance = rn->info;
  893.   if (odistance->access_list)
  894.     free (odistance->access_list);
  895.   ospf_distance_free (odistance);
  896.   rn->info = NULL;
  897.   route_unlock_node (rn);
  898.   route_unlock_node (rn);
  899.   return CMD_SUCCESS;
  900. }
  901. void
  902. ospf_distance_reset (struct ospf *ospf)
  903. {
  904.   struct route_node *rn;
  905.   struct ospf_distance *odistance;
  906.   for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
  907.     if ((odistance = rn->info) != NULL)
  908.       {
  909. if (odistance->access_list)
  910.   free (odistance->access_list);
  911. ospf_distance_free (odistance);
  912. rn->info = NULL;
  913. route_unlock_node (rn);
  914.       }
  915. }
  916. u_char
  917. ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
  918. {
  919.   struct ospf *ospf;
  920.   ospf = ospf_lookup ();
  921.   if (ospf == NULL)
  922.     return 0;
  923.   if (ospf->distance_intra)
  924.     if (or->path_type == OSPF_PATH_INTRA_AREA)
  925.       return ospf->distance_intra;
  926.   if (ospf->distance_inter)
  927.     if (or->path_type == OSPF_PATH_INTER_AREA)
  928.       return ospf->distance_inter;
  929.   if (ospf->distance_external)
  930.     if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
  931. || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
  932.       return ospf->distance_external;
  933.   
  934.   if (ospf->distance_all)
  935.     return ospf->distance_all;
  936.   return 0;
  937. }
  938. void
  939. ospf_zebra_init ()
  940. {
  941.   /* Allocate zebra structure. */
  942.   zclient = zclient_new ();
  943.   zclient_init (zclient, ZEBRA_ROUTE_OSPF);
  944.   zclient->interface_add = ospf_interface_add;
  945.   zclient->interface_delete = ospf_interface_delete;
  946.   zclient->interface_up = ospf_interface_state_up;
  947.   zclient->interface_down = ospf_interface_state_down;
  948.   zclient->interface_address_add = ospf_interface_address_add;
  949.   zclient->interface_address_delete = ospf_interface_address_delete;
  950.   zclient->ipv4_route_add = ospf_zebra_read_ipv4;
  951.   zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
  952.   access_list_add_hook (ospf_filter_update);
  953.   access_list_delete_hook (ospf_filter_update);
  954. }