frr/isisd/isis_zebra.c

620 lines
16 KiB
C
Raw Normal View History

2003-12-23 09:09:43 +01:00
/*
* IS-IS Rout(e)ing protocol - isis_zebra.c
*
* Copyright (C) 2001,2002 Sampo Saaristo
* Tampere University of Technology
* Institute of Communications Engineering
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public Licenseas published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <zebra.h>
#include "thread.h"
#include "command.h"
#include "memory.h"
#include "log.h"
#include "if.h"
#include "network.h"
#include "prefix.h"
#include "zclient.h"
#include "stream.h"
#include "linklist.h"
#include "isisd/dict.h"
2003-12-23 09:09:43 +01:00
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
2012-03-24 16:35:20 +01:00
#include "isisd/isis_flags.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isisd.h"
2003-12-23 09:09:43 +01:00
#include "isisd/isis_circuit.h"
#include "isisd/isis_csm.h"
2012-03-24 16:35:20 +01:00
#include "isisd/isis_lsp.h"
2003-12-23 09:09:43 +01:00
#include "isisd/isis_route.h"
#include "isisd/isis_zebra.h"
struct zclient *zclient = NULL;
2004-10-03 20:18:34 +02:00
/* Router-id update message from zebra. */
static int
2004-10-03 20:18:34 +02:00
isis_router_id_update_zebra (int command, struct zclient *zclient,
zebra_size_t length)
{
2012-03-24 16:35:20 +01:00
struct isis_area *area;
struct listnode *node;
2004-10-03 20:18:34 +02:00
struct prefix router_id;
2012-03-24 16:35:20 +01:00
zebra_router_id_update_read (zclient->ibuf, &router_id);
if (isis->router_id == router_id.u.prefix4.s_addr)
return 0;
isis->router_id = router_id.u.prefix4.s_addr;
for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
if (listcount (area->area_addrs) > 0)
lsp_regenerate_schedule (area, area->is_type, 0);
2004-10-03 20:18:34 +02:00
return 0;
}
2003-12-23 09:09:43 +01:00
static int
2003-12-23 09:09:43 +01:00
isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
{
struct interface *ifp;
ifp = zebra_interface_add_read (zclient->ibuf);
if (isis->debugs & DEBUG_ZEBRA)
zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
if (if_is_operative (ifp))
2003-12-23 09:09:43 +01:00
isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
2003-12-23 09:09:43 +01:00
return 0;
}
static int
2003-12-23 09:09:43 +01:00
isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length)
{
struct interface *ifp;
struct stream *s;
s = zclient->ibuf;
ifp = zebra_interface_state_read (s);
2003-12-23 09:09:43 +01:00
if (!ifp)
return 0;
if (if_is_operative (ifp))
2003-12-23 09:09:43 +01:00
zlog_warn ("Zebra: got delete of %s, but interface is still up",
ifp->name);
2003-12-23 09:09:43 +01:00
if (isis->debugs & DEBUG_ZEBRA)
zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
2003-12-23 09:09:43 +01:00
2012-03-24 16:35:20 +01:00
isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu> Fix problems when netlink interfaces are renamed (same ifindex used for a new interface). Start cleaning up some problems with the way interface names are handled. * interface.c: (if_new_intern_ifindex) Remove obsolete function. (if_delete_update) After distributing the interface deletion message, set ifp->ifindex to IFINDEX_INTERNAL. (if_dump_vty) Detect pseudo interface by checking if ifp->ifindex is IFINDEX_INTERNAL. (zebra_interface) Check return code from interface_cmd.func. Do not set internal ifindex values to if_new_intern_ifindex(), since we now use IFINDEX_INTERNAL for all pseudo interfaces. * kernel_socket.c: (ifm_read) Fix code and comments to reflect that all internal interfaces now have ifp->ifindex set to IFINDEX_INTERNAL. * rt_netlink.c: (set_ifindex) New function used to update ifp->ifindex. Detects interface rename events by checking if that ifindex is already being used. If it is, delete the old interface before assigning the ifindex to the new interface. (netlink_interface, netlink_link_change) Call set_ifindex to update the ifindex. * if.h: Remove define for IFINDEX_INTERNBASE and add define IFINDEX_INTERNAL 0, since all internal (i.e. non-kernel) pseudo- interfaces should have ifindex set to 0. (if_new) Remove function. (if_delete_retain) New function to delete an interface without removing from iflist and freeing the structure. (ifname2ifindex) New function. * if.c: (if_new) Remove function (absorb into if_create). (if_create) Replace function if_new with call to calloc. Set ifp->ifindex to IFINDEX_INTERNAL. Fix off-by-one error in assert to check length of interface name. Add error message if interface with this name already exists. (if_delete_retain) New function to delete an interface without removing from iflist and freeing the structure. (if_delete) Implement with help of if_delete_retain. (ifindex2ifname) Reimplement using if_lookup_by_index. (ifname2ifindex) New function to complement ifindex2ifname. (interface) The interface command should check the name length and fail with a warning message if it is too long. (no_interface) Fix spelling in warning message. (if_nametoindex) Reimplement using if_lookup_by_name. (if_indextoname, ifaddr_ipv4_lookup) Reimplement using if_lookup_by_index. * bgp_zebra.c: (bgp_interface_delete) After deleting, set ifp->ifindex to IFINDEX_INTERNAL. * isis_zebra.c: (isis_zebra_if_del) Call if_delete_retain instead of if_delete, since it is generally not safe to remove interface structures. After deleting, set ifp->ifindex to IFINDEX_INTERNAL. (zebra_interface_if_lookup) Tighten up code. * ospf6_zebra.c: (ospf6_zebra_if_del) Previously, this whole function was commented out. But this is not safe: we should at least update the ifindex when the interface is deleted. So the new version updates the interface status and sets ifp->ifindex to IFINDEX_INTERNAL. (ospf6_zebra_route_update) Use if_indextoname properly. * ospf_vty.c: (show_ip_ospf_interface_sub) Show ifindex and interface flags to help with debugging. * ospf_zebra.c: (ospf_interface_delete) After deleting, set ifp->ifindex to IFINDEX_INTERNAL. (zebra_interface_if_lookup) Make function static. Tighten up code. * rip_interface.c: (rip_interface_delete) After deleting, set ifp->ifindex to IFINDEX_INTERNAL. * ripng_interface.c: (ripng_interface_delete) After deleting, set ifp->ifindex to IFINDEX_INTERNAL.
2005-04-02 20:38:43 +02:00
/* Cannot call if_delete because we should retain the pseudo interface
in case there is configuration info attached to it. */
if_delete_retain(ifp);
2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu> Fix problems when netlink interfaces are renamed (same ifindex used for a new interface). Start cleaning up some problems with the way interface names are handled. * interface.c: (if_new_intern_ifindex) Remove obsolete function. (if_delete_update) After distributing the interface deletion message, set ifp->ifindex to IFINDEX_INTERNAL. (if_dump_vty) Detect pseudo interface by checking if ifp->ifindex is IFINDEX_INTERNAL. (zebra_interface) Check return code from interface_cmd.func. Do not set internal ifindex values to if_new_intern_ifindex(), since we now use IFINDEX_INTERNAL for all pseudo interfaces. * kernel_socket.c: (ifm_read) Fix code and comments to reflect that all internal interfaces now have ifp->ifindex set to IFINDEX_INTERNAL. * rt_netlink.c: (set_ifindex) New function used to update ifp->ifindex. Detects interface rename events by checking if that ifindex is already being used. If it is, delete the old interface before assigning the ifindex to the new interface. (netlink_interface, netlink_link_change) Call set_ifindex to update the ifindex. * if.h: Remove define for IFINDEX_INTERNBASE and add define IFINDEX_INTERNAL 0, since all internal (i.e. non-kernel) pseudo- interfaces should have ifindex set to 0. (if_new) Remove function. (if_delete_retain) New function to delete an interface without removing from iflist and freeing the structure. (ifname2ifindex) New function. * if.c: (if_new) Remove function (absorb into if_create). (if_create) Replace function if_new with call to calloc. Set ifp->ifindex to IFINDEX_INTERNAL. Fix off-by-one error in assert to check length of interface name. Add error message if interface with this name already exists. (if_delete_retain) New function to delete an interface without removing from iflist and freeing the structure. (if_delete) Implement with help of if_delete_retain. (ifindex2ifname) Reimplement using if_lookup_by_index. (ifname2ifindex) New function to complement ifindex2ifname. (interface) The interface command should check the name length and fail with a warning message if it is too long. (no_interface) Fix spelling in warning message. (if_nametoindex) Reimplement using if_lookup_by_name. (if_indextoname, ifaddr_ipv4_lookup) Reimplement using if_lookup_by_index. * bgp_zebra.c: (bgp_interface_delete) After deleting, set ifp->ifindex to IFINDEX_INTERNAL. * isis_zebra.c: (isis_zebra_if_del) Call if_delete_retain instead of if_delete, since it is generally not safe to remove interface structures. After deleting, set ifp->ifindex to IFINDEX_INTERNAL. (zebra_interface_if_lookup) Tighten up code. * ospf6_zebra.c: (ospf6_zebra_if_del) Previously, this whole function was commented out. But this is not safe: we should at least update the ifindex when the interface is deleted. So the new version updates the interface status and sets ifp->ifindex to IFINDEX_INTERNAL. (ospf6_zebra_route_update) Use if_indextoname properly. * ospf_vty.c: (show_ip_ospf_interface_sub) Show ifindex and interface flags to help with debugging. * ospf_zebra.c: (ospf_interface_delete) After deleting, set ifp->ifindex to IFINDEX_INTERNAL. (zebra_interface_if_lookup) Make function static. Tighten up code. * rip_interface.c: (rip_interface_delete) After deleting, set ifp->ifindex to IFINDEX_INTERNAL. * ripng_interface.c: (ripng_interface_delete) After deleting, set ifp->ifindex to IFINDEX_INTERNAL.
2005-04-02 20:38:43 +02:00
ifp->ifindex = IFINDEX_INTERNAL;
2003-12-23 09:09:43 +01:00
return 0;
}
static int
isis_zebra_if_state_up (int command, struct zclient *zclient,
2003-12-23 09:09:43 +01:00
zebra_size_t length)
{
struct interface *ifp;
2012-03-24 16:35:20 +01:00
ifp = zebra_interface_state_read (zclient->ibuf);
2012-03-24 16:35:20 +01:00
if (ifp == NULL)
2003-12-23 09:09:43 +01:00
return 0;
2003-12-23 09:09:43 +01:00
isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
2003-12-23 09:09:43 +01:00
return 0;
}
static int
isis_zebra_if_state_down (int command, struct zclient *zclient,
2003-12-23 09:09:43 +01:00
zebra_size_t length)
{
struct interface *ifp;
2012-03-24 16:35:20 +01:00
struct isis_circuit *circuit;
2012-03-24 16:35:20 +01:00
ifp = zebra_interface_state_read (zclient->ibuf);
2003-12-23 09:09:43 +01:00
if (ifp == NULL)
return 0;
2012-03-24 16:35:20 +01:00
circuit = isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp),
ifp);
if (circuit)
SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
2003-12-23 09:09:43 +01:00
return 0;
}
static int
isis_zebra_if_address_add (int command, struct zclient *zclient,
zebra_size_t length)
2003-12-23 09:09:43 +01:00
{
struct connected *c;
struct prefix *p;
2004-09-26 18:24:14 +02:00
char buf[BUFSIZ];
2003-12-23 09:09:43 +01:00
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
zclient->ibuf);
2003-12-23 09:09:43 +01:00
if (c == NULL)
return 0;
2003-12-23 09:09:43 +01:00
p = c->address;
2003-12-23 09:09:43 +01:00
prefix2str (p, buf, BUFSIZ);
#ifdef EXTREME_DEBUG
if (p->family == AF_INET)
zlog_debug ("connected IP address %s", buf);
2003-12-23 09:09:43 +01:00
#ifdef HAVE_IPV6
if (p->family == AF_INET6)
zlog_debug ("connected IPv6 address %s", buf);
2003-12-23 09:09:43 +01:00
#endif /* HAVE_IPV6 */
#endif /* EXTREME_DEBUG */
if (if_is_operative (c->ifp))
isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
2003-12-23 09:09:43 +01:00
return 0;
}
static int
isis_zebra_if_address_del (int command, struct zclient *client,
zebra_size_t length)
2003-12-23 09:09:43 +01:00
{
struct connected *c;
struct interface *ifp;
2004-10-07 22:07:40 +02:00
#ifdef EXTREME_DEBUG
struct prefix *p;
u_char buf[BUFSIZ];
2004-10-07 22:07:40 +02:00
#endif /* EXTREME_DEBUG */
2003-12-23 09:09:43 +01:00
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
zclient->ibuf);
2003-12-23 09:09:43 +01:00
if (c == NULL)
return 0;
2003-12-23 09:09:43 +01:00
ifp = c->ifp;
#ifdef EXTREME_DEBUG
p = c->address;
prefix2str (p, buf, BUFSIZ);
if (p->family == AF_INET)
zlog_debug ("disconnected IP address %s", buf);
#ifdef HAVE_IPV6
if (p->family == AF_INET6)
zlog_debug ("disconnected IPv6 address %s", buf);
#endif /* HAVE_IPV6 */
#endif /* EXTREME_DEBUG */
if (if_is_operative (ifp))
isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
connected_free (c);
2003-12-23 09:09:43 +01:00
return 0;
}
static void
isis_zebra_route_add_ipv4 (struct prefix *prefix,
struct isis_route_info *route_info)
2003-12-23 09:09:43 +01:00
{
u_char message, flags;
int psize;
struct stream *stream;
struct isis_nexthop *nexthop;
struct listnode *node;
2012-03-24 16:35:20 +01:00
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
2003-12-23 09:09:43 +01:00
return;
if (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS].enabled)
{
message = 0;
flags = 0;
SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (message, ZAPI_MESSAGE_METRIC);
#if 0
SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
#endif
stream = zclient->obuf;
stream_reset (stream);
zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD);
/* type */
stream_putc (stream, ZEBRA_ROUTE_ISIS);
Multi-Instance OSPF Summary ——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
/* instance */
stream_putw (stream, 0);
/* flags */
stream_putc (stream, flags);
/* message */
stream_putc (stream, message);
/* SAFI */
stream_putw (stream, SAFI_UNICAST);
/* prefix information */
psize = PSIZE (prefix->prefixlen);
stream_putc (stream, prefix->prefixlen);
stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
stream_putc (stream, listcount (route_info->nexthops));
/* Nexthop, ifindex, distance and metric information */
for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
{
/* FIXME: can it be ? */
if (nexthop->ip.s_addr != INADDR_ANY)
{
stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
stream_put_in_addr (stream, &nexthop->ip);
}
else
{
stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
stream_putl (stream, nexthop->ifindex);
}
}
#if 0
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
stream_putc (stream, route_info->depth);
#endif
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
stream_putl (stream, route_info->cost);
stream_putw_at (stream, 0, stream_get_endp (stream));
2005-04-11 Andrew J. Schorr <ajschorr@alumni.princeton.edu> Implement non-blocking zclient I/O with buffering. * zclient.h (struct zclient): Add two fields to support non-blocking I/O: struct buffer *wb, and struct thread *t_write. (zclient_free): Remove function. (zebra_redistribute_send): Change 2nd arg from socket fd to struct zclient * (needed to support non-blocking I/O and buffering). (zclient_send_message): New function to send an arbitrary message with non-blocking I/O. * zclient.c (zclient_new): Create write buffer. (zclient_free): Remove unused function. (zclient_stop): Must cancel new t_write thread. Also, reset all buffers: ibuf, obuf, and wb. (zclient_failed): New helper function for typical error handling. (zclient_flush_data): New thread to flush queued data. (zclient_send_message): New function to send the message in zclient->obuf to zebra using non-blocking I/O and buffering. (zebra_message_send, zapi_ipv4_route, zapi_ipv6_route): Use new zclient_send_message function instead of calling writen. (zclient_start): Set socket non-blocking. Also, change 2nd arg to zebra_redistribute_send from zclient->sock to zclient. (zebra_redistribute_send): Change 2nd arg to struct zclient *. Can now use zclient->obuf to assemble the message instead of allocating a temporary stream. And call zclient_send_message to send the message instead of writen. (zclient_read): Convert to support non-blocking I/O by using stream_read_try instead of deprecated stream_read. (zclient_redistribute): Change 2nd arg to zebra_redistribute_send from zclient->sock to zclient. * ospf6_zebra.c (ospf6_zebra_redistribute, ospf6_zebra_no_redistribute): Change 2nd arg to zebra_redistribute_send from zclient->sock to zclient. * ospf_zebra.c (ospf_zebra_add): Call zclient_send_message instead of writen. * rip_zebra.c (rip_redistribute_set, rip_redistribute_unset, rip_redistribute_clean): Change 2nd arg to zebra_redistribute_send from zclient->sock to zclient. * ripng_zebra.c (ripng_redistribute_unset, ripng_redistribute_clean): Change 2nd arg to zebra_redistribute_send from zclient->sock to zclient. * bgp_zebra.c (bgp_redistribute_set, bgp_redistribute_unset): The 2nd arg to zebra_redistribute_send is now zclient instead of zclient->sock. * isis_zebra.h (isis_zebra_finish): Remove declaration of unused function. * isis_zebra.c (isis_zebra_route_add_ipv4): Call zclient_send_message to send the message to zebra instead of calling writen directly, since zclient_send_message understands non-blocking I/O and will manage the buffer queue appropriately. (isis_zebra_finish): Remove unused function, particularly since the zclient_free function has been removed.
2005-04-11 17:51:40 +02:00
zclient_send_message(zclient);
2012-03-24 16:35:20 +01:00
SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
}
2003-12-23 09:09:43 +01:00
}
static void
isis_zebra_route_del_ipv4 (struct prefix *prefix,
struct isis_route_info *route_info)
2003-12-23 09:09:43 +01:00
{
struct zapi_ipv4 api;
struct prefix_ipv4 prefix4;
if (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS].enabled)
{
api.type = ZEBRA_ROUTE_ISIS;
Multi-Instance OSPF Summary ——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
api.instance = 0;
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
prefix4.family = AF_INET;
prefix4.prefixlen = prefix->prefixlen;
prefix4.prefix = prefix->u.prefix4;
zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
}
2012-03-24 16:35:20 +01:00
UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
2003-12-23 09:09:43 +01:00
return;
}
#ifdef HAVE_IPV6
static void
2003-12-23 09:09:43 +01:00
isis_zebra_route_add_ipv6 (struct prefix *prefix,
struct isis_route_info *route_info)
2003-12-23 09:09:43 +01:00
{
struct zapi_ipv6 api;
struct in6_addr **nexthop_list;
unsigned int *ifindex_list;
struct isis_nexthop6 *nexthop6;
int i, size;
struct listnode *node;
struct prefix_ipv6 prefix6;
2012-03-24 16:35:20 +01:00
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
2003-12-23 09:09:43 +01:00
return;
2003-12-23 09:09:43 +01:00
api.type = ZEBRA_ROUTE_ISIS;
Multi-Instance OSPF Summary ——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
api.instance = 0;
2003-12-23 09:09:43 +01:00
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
2003-12-23 09:09:43 +01:00
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = route_info->cost;
#if 0
SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
api.distance = route_info->depth;
#endif
api.nexthop_num = listcount (route_info->nexthops6);
api.ifindex_num = listcount (route_info->nexthops6);
2003-12-23 09:09:43 +01:00
/* allocate memory for nexthop_list */
size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
if (!nexthop_list)
{
zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
return;
}
2003-12-23 09:09:43 +01:00
/* allocate memory for ifindex_list */
size = sizeof (unsigned int) * listcount (route_info->nexthops6);
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
if (!ifindex_list)
{
zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
XFREE (MTYPE_ISIS_TMP, nexthop_list);
return;
}
2003-12-23 09:09:43 +01:00
/* for each nexthop */
i = 0;
for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
{
if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
!IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
{
api.nexthop_num--;
api.ifindex_num--;
continue;
}
nexthop_list[i] = &nexthop6->ip6;
ifindex_list[i] = nexthop6->ifindex;
i++;
2003-12-23 09:09:43 +01:00
}
2003-12-23 09:09:43 +01:00
api.nexthop = nexthop_list;
api.ifindex = ifindex_list;
if (api.nexthop_num && api.ifindex_num)
{
prefix6.family = AF_INET6;
prefix6.prefixlen = prefix->prefixlen;
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
2012-03-24 16:35:20 +01:00
SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
}
2003-12-23 09:09:43 +01:00
XFREE (MTYPE_ISIS_TMP, nexthop_list);
XFREE (MTYPE_ISIS_TMP, ifindex_list);
2003-12-23 09:09:43 +01:00
return;
}
static void
isis_zebra_route_del_ipv6 (struct prefix *prefix,
struct isis_route_info *route_info)
2003-12-23 09:09:43 +01:00
{
struct zapi_ipv6 api;
struct in6_addr **nexthop_list;
unsigned int *ifindex_list;
struct isis_nexthop6 *nexthop6;
int i, size;
struct listnode *node;
struct prefix_ipv6 prefix6;
2012-03-24 16:35:20 +01:00
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
2003-12-23 09:09:43 +01:00
return;
2003-12-23 09:09:43 +01:00
api.type = ZEBRA_ROUTE_ISIS;
Multi-Instance OSPF Summary ——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
api.instance = 0;
2003-12-23 09:09:43 +01:00
api.flags = 0;
api.message = 0;
api.safi = SAFI_UNICAST;
2003-12-23 09:09:43 +01:00
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
api.nexthop_num = listcount (route_info->nexthops6);
api.ifindex_num = listcount (route_info->nexthops6);
2003-12-23 09:09:43 +01:00
/* allocate memory for nexthop_list */
size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
if (!nexthop_list)
{
zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
return;
}
2003-12-23 09:09:43 +01:00
/* allocate memory for ifindex_list */
size = sizeof (unsigned int) * listcount (route_info->nexthops6);
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
if (!ifindex_list)
{
zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
XFREE (MTYPE_ISIS_TMP, nexthop_list);
return;
}
2003-12-23 09:09:43 +01:00
/* for each nexthop */
i = 0;
for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
{
if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
!IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
{
api.nexthop_num--;
api.ifindex_num--;
continue;
}
nexthop_list[i] = &nexthop6->ip6;
ifindex_list[i] = nexthop6->ifindex;
i++;
2003-12-23 09:09:43 +01:00
}
2003-12-23 09:09:43 +01:00
api.nexthop = nexthop_list;
api.ifindex = ifindex_list;
if (api.nexthop_num && api.ifindex_num)
{
prefix6.family = AF_INET6;
prefix6.prefixlen = prefix->prefixlen;
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
2012-03-24 16:35:20 +01:00
UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
}
2003-12-23 09:09:43 +01:00
XFREE (MTYPE_ISIS_TMP, nexthop_list);
XFREE (MTYPE_ISIS_TMP, ifindex_list);
2003-12-23 09:09:43 +01:00
}
#endif /* HAVE_IPV6 */
void
isis_zebra_route_update (struct prefix *prefix,
struct isis_route_info *route_info)
2003-12-23 09:09:43 +01:00
{
if (zclient->sock < 0)
return;
if ((prefix->family == AF_INET && !zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS].enabled) ||
(prefix->family == AF_INET6 && !zclient->redist[AFI_IP6][ZEBRA_ROUTE_ISIS].enabled))
2003-12-23 09:09:43 +01:00
return;
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
{
if (prefix->family == AF_INET)
isis_zebra_route_add_ipv4 (prefix, route_info);
2003-12-23 09:09:43 +01:00
#ifdef HAVE_IPV6
else if (prefix->family == AF_INET6)
isis_zebra_route_add_ipv6 (prefix, route_info);
2003-12-23 09:09:43 +01:00
#endif /* HAVE_IPV6 */
}
else
{
if (prefix->family == AF_INET)
isis_zebra_route_del_ipv4 (prefix, route_info);
2003-12-23 09:09:43 +01:00
#ifdef HAVE_IPV6
else if (prefix->family == AF_INET6)
isis_zebra_route_del_ipv6 (prefix, route_info);
2003-12-23 09:09:43 +01:00
#endif /* HAVE_IPV6 */
}
2003-12-23 09:09:43 +01:00
return;
}
static int
isis_zebra_read_ipv4 (int command, struct zclient *zclient,
2003-12-23 09:09:43 +01:00
zebra_size_t length)
{
struct stream *stream;
struct zapi_ipv4 api;
struct prefix_ipv4 p;
stream = zclient->ibuf;
memset (&p, 0, sizeof (struct prefix_ipv4));
api.type = stream_getc (stream);
Multi-Instance OSPF Summary ——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
api.instance = stream_getw (stream);
api.flags = stream_getc (stream);
2003-12-23 09:09:43 +01:00
api.message = stream_getc (stream);
p.family = AF_INET;
p.prefixlen = stream_getc (stream);
stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
2003-12-23 09:09:43 +01:00
api.nexthop_num = stream_getc (stream);
(void)stream_get_ipv4 (stream);
}
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
{
api.ifindex_num = stream_getc (stream);
stream_getl (stream);
}
2003-12-23 09:09:43 +01:00
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
api.distance = stream_getc (stream);
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
api.metric = stream_getl (stream);
else
api.metric = 0;
if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD)
{
if (isis->debugs & DEBUG_ZEBRA)
zlog_debug ("IPv4 Route add from Z");
}
2003-12-23 09:09:43 +01:00
return 0;
}
#ifdef HAVE_IPV6
static int
isis_zebra_read_ipv6 (int command, struct zclient *zclient,
2003-12-23 09:09:43 +01:00
zebra_size_t length)
{
return 0;
}
#endif
2003-12-23 09:09:43 +01:00
#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
Multi-Instance OSPF Summary ——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
T == ZEBRA_ROUTE_MAX ? zclient->default_information : \
(zclient->redist[AFI_IP][type].enabled || client->redist[AFI_IP6][type].enabled)
2003-12-23 09:09:43 +01:00
int
isis_distribute_list_update (int routetype)
{
return 0;
}
#if 0 /* Not yet. */
static int
isis_redistribute_default_set (int routetype, int metric_type,
int metric_value)
2003-12-23 09:09:43 +01:00
{
return 0;
}
#endif /* 0 */
2003-12-23 09:09:43 +01:00
void
isis_zebra_init (struct thread_master *master)
2003-12-23 09:09:43 +01:00
{
zclient = zclient_new(master);
Multi-Instance OSPF Summary ——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
zclient_init (zclient, ZEBRA_ROUTE_ISIS, 0);
2004-10-03 20:18:34 +02:00
zclient->router_id_update = isis_router_id_update_zebra;
2003-12-23 09:09:43 +01:00
zclient->interface_add = isis_zebra_if_add;
zclient->interface_delete = isis_zebra_if_del;
zclient->interface_up = isis_zebra_if_state_up;
zclient->interface_down = isis_zebra_if_state_down;
zclient->interface_address_add = isis_zebra_if_address_add;
zclient->interface_address_delete = isis_zebra_if_address_del;
zclient->ipv4_route_add = isis_zebra_read_ipv4;
zclient->ipv4_route_delete = isis_zebra_read_ipv4;
zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4;
zclient->redistribute_route_ipv4_del = isis_zebra_read_ipv4;
2003-12-23 09:09:43 +01:00
#ifdef HAVE_IPV6
zclient->ipv6_route_add = isis_zebra_read_ipv6;
zclient->ipv6_route_delete = isis_zebra_read_ipv6;
zclient->redistribute_route_ipv6_add = isis_zebra_read_ipv6;
zclient->redistribute_route_ipv6_del = isis_zebra_read_ipv6;
2003-12-23 09:09:43 +01:00
#endif /* HAVE_IPV6 */
return;
}