frr/zebra/zserv.c

2560 lines
67 KiB
C
Raw Normal View History

2002-12-13 21:15:29 +01:00
/* Zebra daemon server routine.
* Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <zebra.h>
#include "prefix.h"
#include "command.h"
#include "if.h"
#include "thread.h"
#include "stream.h"
#include "memory.h"
#include "table.h"
#include "rib.h"
#include "network.h"
#include "sockunion.h"
#include "log.h"
#include "zclient.h"
#include "privs.h"
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
#include "network.h"
#include "buffer.h"
#include "nexthop.h"
#include "vrf.h"
2002-12-13 21:15:29 +01:00
#include "zebra/zserv.h"
2004-10-03 20:18:34 +02:00
#include "zebra/router-id.h"
2002-12-13 21:15:29 +01:00
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/ipforward.h"
#include "zebra/zebra_rnh.h"
2015-06-11 18:19:59 +02:00
#include "zebra/rt_netlink.h"
#include "zebra/interface.h"
#include "zebra/zebra_ptm.h"
2002-12-13 21:15:29 +01:00
/* Event list of zebra. */
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
extern struct zebra_t zebrad;
2002-12-13 21:15:29 +01:00
static void zebra_event (enum event event, int sock, struct zserv *client);
2003-03-01 12:42:20 +01:00
extern struct zebra_privs_t zserv_privs;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static void zebra_client_close (struct zserv *client);
2003-03-01 12:42:20 +01:00
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
zserv_delayed_close(struct thread *thread)
2003-03-01 12:42:20 +01:00
{
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
struct zserv *client = THREAD_ARG(thread);
2003-03-01 12:42:20 +01:00
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
client->t_suicide = NULL;
zebra_client_close(client);
2003-03-01 12:42:20 +01:00
return 0;
}
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
zserv_flush_data(struct thread *thread)
2003-03-01 12:42:20 +01:00
{
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
struct zserv *client = THREAD_ARG(thread);
2003-03-01 12:42:20 +01:00
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
client->t_write = NULL;
if (client->t_suicide)
2003-03-01 12:42:20 +01:00
{
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
zebra_client_close(client);
return -1;
2003-03-01 12:42:20 +01:00
}
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
switch (buffer_flush_available(client->wb, client->sock))
2003-03-01 12:42:20 +01:00
{
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
case BUFFER_ERROR:
zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, "
"closing", __func__, client->sock);
zebra_client_close(client);
break;
case BUFFER_PENDING:
client->t_write = thread_add_write(zebrad.master, zserv_flush_data,
client, client->sock);
break;
case BUFFER_EMPTY:
break;
2003-03-01 12:42:20 +01:00
}
client->last_write_time = quagga_time(NULL);
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
}
2003-03-01 12:42:20 +01:00
int
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
zebra_server_send_message(struct zserv *client)
{
if (client->t_suicide)
return -1;
stream_set_getp(client->obuf, 0);
client->last_write_cmd = stream_getw_from(client->obuf, 4);
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf),
stream_get_endp(client->obuf)))
{
case BUFFER_ERROR:
zlog_warn("%s: buffer_write failed to zserv client fd %d, closing",
__func__, client->sock);
/* Schedule a delayed close since many of the functions that call this
one do not check the return code. They do not allow for the
possibility that an I/O error may have caused the client to be
deleted. */
client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
client, 0);
return -1;
case BUFFER_EMPTY:
THREAD_OFF(client->t_write);
break;
case BUFFER_PENDING:
THREAD_WRITE_ON(zebrad.master, client->t_write,
zserv_flush_data, client, client->sock);
break;
}
client->last_write_time = quagga_time(NULL);
2003-03-01 12:42:20 +01:00
return 0;
}
void
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (struct stream *s, uint16_t cmd, vrf_id_t vrf_id)
{
/* length placeholder, caller can update */
stream_putw (s, ZEBRA_HEADER_SIZE);
stream_putc (s, ZEBRA_HEADER_MARKER);
stream_putc (s, ZSERV_VERSION);
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
stream_putw (s, vrf_id);
stream_putw (s, cmd);
}
static void
zserv_encode_interface (struct stream *s, struct interface *ifp)
{
/* Interface information. */
stream_put (s, ifp->name, INTERFACE_NAMSIZ);
stream_putl (s, ifp->ifindex);
stream_putc (s, ifp->status);
stream_putq (s, ifp->flags);
stream_putc (s, ifp->ptm_enable);
stream_putc (s, ifp->ptm_status);
stream_putl (s, ifp->metric);
stream_putl (s, ifp->mtu);
stream_putl (s, ifp->mtu6);
stream_putl (s, ifp->bandwidth);
#ifdef HAVE_STRUCT_SOCKADDR_DL
stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage));
#else
stream_putl (s, ifp->hw_addr_len);
if (ifp->hw_addr_len)
stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
#endif /* HAVE_STRUCT_SOCKADDR_DL */
/* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s));
}
2002-12-13 21:15:29 +01:00
/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
/*
* This function is called in the following situations:
* - in response to a 3-byte ZEBRA_INTERFACE_ADD request
* from the client.
* - at startup, when zebra figures out the available interfaces
* - when an interface is added (where support for
* RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
* an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
* received)
*/
2002-12-13 21:15:29 +01:00
int
zsend_interface_add (struct zserv *client, struct interface *ifp)
{
struct stream *s;
/* Check this client need interface information. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
s = client->obuf;
stream_reset (s);
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id);
zserv_encode_interface (s, ifp);
2002-12-13 21:15:29 +01:00
client->ifadd_cnt++;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return zebra_server_send_message(client);
2002-12-13 21:15:29 +01:00
}
/* Interface deletion from zebra daemon. */
int
zsend_interface_delete (struct zserv *client, struct interface *ifp)
{
struct stream *s;
/* Check this client need interface information. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
s = client->obuf;
stream_reset (s);
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id);
zserv_encode_interface (s, ifp);
2002-12-13 21:15:29 +01:00
client->ifdel_cnt++;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return zebra_server_send_message (client);
2002-12-13 21:15:29 +01:00
}
/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
* ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
*
* A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
* - in response to a 3-byte ZEBRA_INTERFACE_ADD request
* from the client, after the ZEBRA_INTERFACE_ADD has been
* sent from zebra to the client
* - redistribute new address info to all clients in the following situations
* - at startup, when zebra figures out the available interfaces
* - when an interface is added (where support for
* RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
* an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
* received)
* - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"
* and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
* - when an RTM_NEWADDR message is received from the kernel,
*
* The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
*
* zsend_interface_address(DELETE)
* ^
* |
* zebra_interface_address_delete_update
* ^ ^ ^
* | | if_delete_update
* | |
* ip_address_uninstall connected_delete_ipv4
* [ipv6_addresss_uninstall] [connected_delete_ipv6]
* ^ ^
* | |
* | RTM_NEWADDR on routing/netlink socket
* |
* vty commands:
* "no ip address A.B.C.D/M [label LINE]"
* "no ip address A.B.C.D/M secondary"
* ["no ipv6 address X:X::X:X/M"]
*
*/
2002-12-13 21:15:29 +01:00
int
zsend_interface_address (int cmd, struct zserv *client,
struct interface *ifp, struct connected *ifc)
2002-12-13 21:15:29 +01:00
{
int blen;
struct stream *s;
struct prefix *p;
/* Check this client need interface information. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
s = client->obuf;
stream_reset (s);
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, cmd, ifp->vrf_id);
2002-12-13 21:15:29 +01:00
stream_putl (s, ifp->ifindex);
/* Interface address flag. */
stream_putc (s, ifc->flags);
/* Prefix information. */
p = ifc->address;
stream_putc (s, p->family);
blen = prefix_blen (p);
stream_put (s, &p->u.prefix, blen);
/*
* XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
* but zebra_interface_address_delete_read() in the gnu version
* expects to find it
*/
2002-12-13 21:15:29 +01:00
stream_putc (s, p->prefixlen);
/* Destination. */
p = ifc->destination;
if (p)
stream_put (s, &p->u.prefix, blen);
else
stream_put (s, NULL, blen);
/* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s));
client->connected_rt_add_cnt++;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return zebra_server_send_message(client);
2002-12-13 21:15:29 +01:00
}
static int
zsend_interface_nbr_address (int cmd, struct zserv *client,
struct interface *ifp, struct nbr_connected *ifc)
{
int blen;
struct stream *s;
struct prefix *p;
/* Check this client need interface information. */
if (! client->ifinfo)
return 0;
s = client->obuf;
stream_reset (s);
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, cmd, ifp->vrf_id);
stream_putl (s, ifp->ifindex);
/* Prefix information. */
p = ifc->address;
stream_putc (s, p->family);
blen = prefix_blen (p);
stream_put (s, &p->u.prefix, blen);
/*
* XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE
* but zebra_interface_address_delete_read() in the gnu version
* expects to find it
*/
stream_putc (s, p->prefixlen);
/* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s));
return zebra_server_send_message(client);
}
/* Interface address addition. */
static void
zebra_interface_nbr_address_add_update (struct interface *ifp,
struct nbr_connected *ifc)
{
struct listnode *node, *nnode;
struct zserv *client;
struct prefix *p;
if (IS_ZEBRA_DEBUG_EVENT)
{
char buf[INET6_ADDRSTRLEN];
p = ifc->address;
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s",
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
p->prefixlen, ifc->ifp->name);
}
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
if (client->ifinfo)
zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, ifp, ifc);
}
/* Interface address deletion. */
static void
zebra_interface_nbr_address_delete_update (struct interface *ifp,
struct nbr_connected *ifc)
{
struct listnode *node, *nnode;
struct zserv *client;
struct prefix *p;
if (IS_ZEBRA_DEBUG_EVENT)
{
char buf[INET6_ADDRSTRLEN];
p = ifc->address;
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s",
inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN),
p->prefixlen, ifc->ifp->name);
}
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
if (client->ifinfo)
zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc);
}
/* Add new nbr connected IPv6 address if none exists already, or replace the
existing one if an ifc entry is found on the interface. */
void
nbr_connected_replacement_add_ipv6 (struct interface *ifp, struct in6_addr *address,
u_char prefixlen)
{
struct nbr_connected *ifc;
struct prefix p;
p.family = AF_INET6;
IPV6_ADDR_COPY (&p.u.prefix, address);
p.prefixlen = prefixlen;
if (nbr_connected_check(ifp, &p))
return;
if (!(ifc = listnode_head(ifp->nbr_connected)))
{
/* new addition */
ifc = nbr_connected_new ();
ifc->address = prefix_new();
ifc->ifp = ifp;
listnode_add (ifp->nbr_connected, ifc);
}
prefix_copy(ifc->address, &p);
zebra_interface_nbr_address_add_update (ifp, ifc);
2015-06-11 18:19:59 +02:00
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 1);
}
void
nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
u_char prefixlen)
{
struct nbr_connected *ifc;
struct prefix p;
p.family = AF_INET6;
IPV6_ADDR_COPY (&p.u.prefix, address);
p.prefixlen = prefixlen;
ifc = nbr_connected_check(ifp, &p);
if (!ifc)
return;
listnode_delete (ifp->nbr_connected, ifc);
zebra_interface_nbr_address_delete_update (ifp, ifc);
2015-06-11 18:19:59 +02:00
if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 0);
nbr_connected_free (ifc);
}
/*
* The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or
* ZEBRA_INTERFACE_DOWN.
*
* The ZEBRA_INTERFACE_UP message is sent from the zebra server to
* the clients in one of 2 situations:
* - an if_up is detected e.g., as a result of an RTM_IFINFO message
* - a vty command modifying the bandwidth of an interface is received.
* The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
*/
2002-12-13 21:15:29 +01:00
int
zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
2002-12-13 21:15:29 +01:00
{
struct stream *s;
/* Check this client need interface information. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
s = client->obuf;
stream_reset (s);
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, cmd, ifp->vrf_id);
zserv_encode_interface (s, ifp);
2002-12-13 21:15:29 +01:00
if (cmd == ZEBRA_INTERFACE_UP)
client->ifup_cnt++;
else
client->ifdown_cnt++;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return zebra_server_send_message(client);
2002-12-13 21:15:29 +01:00
}
/*
* This is the new function to announce and withdraw redistributed routes, used
* by Zebra. This is the old zsend_route_multipath() function. That function
* was duplicating code to send a lot of information that was essentially thrown
* away or ignored by the receiver. This is the leaner function that is not a
* duplicate of the zapi_ipv4_route_add/del.
*
* The primary difference is that this function merely sends a single NH instead of
* all the nexthops.
*/
2002-12-13 21:15:29 +01:00
int
zsend_redistribute_route (int cmd, struct zserv *client, struct prefix *p,
struct rib *rib)
2002-12-13 21:15:29 +01:00
{
int psize;
struct stream *s;
struct nexthop *nexthop;
unsigned long nhnummark = 0, messmark = 0;
int nhnum = 0;
u_char zapi_flags = 0;
struct nexthop dummy_nh;
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
/* Came from VRF lib patch, is this really needed? callers of this routine
do check for redist.., so may be its not needed.
Check this client need this route.
if (!vrf_bitmap_check (client->redist[family2afi(p->family)][rib->type],
rib->vrf_id) &&
!(is_default (p) &&
vrf_bitmap_check (client->redist_default, rib->vrf_id)))
return 0;
*/
2002-12-13 21:15:29 +01:00
s = client->obuf;
stream_reset (s);
memset(&dummy_nh, 0, sizeof(struct nexthop));
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, cmd, rib->vrf_id);
/* Put type and nexthop. */
2002-12-13 21:15:29 +01:00
stream_putc (s, rib->type);
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
stream_putw (s, rib->instance);
2002-12-13 21:15:29 +01:00
stream_putc (s, rib->flags);
/* marker for message flags field */
messmark = stream_get_endp (s);
stream_putc (s, 0);
2002-12-13 21:15:29 +01:00
/* Prefix. */
psize = PSIZE (p->prefixlen);
stream_putc (s, p->prefixlen);
stream_write (s, (u_char *) & p->u.prefix, psize);
2002-12-13 21:15:29 +01:00
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
{
/* We don't send any nexthops when there's a multipath */
if (rib->nexthop_active_num > 1)
{
SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
stream_putc(s, 1);
if (p->family == AF_INET)
{
stream_put_in_addr (s, &dummy_nh.gate.ipv4);
}
else if (p->family == AF_INET6)
{
stream_write (s, (u_char *) &dummy_nh.gate.ipv6, 16);
}
else
{
/* We don't handle anything else now, abort */
zlog_err("%s: Unable to redistribute route of unknown family, %d\n",
__func__, p->family);
return -1;
}
stream_putc (s, 1);
stream_putl (s, 0); /* dummy ifindex */
break;
}
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
|| nexthop_has_fib_child(nexthop))
{
SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
if (nhnummark == 0)
{
nhnummark = stream_get_endp (s);
stream_putc (s, 1); /* placeholder */
}
nhnum++;
switch(nexthop->type)
{
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
stream_put_in_addr (s, &nexthop->gate.ipv4);
break;
2002-12-13 21:15:29 +01:00
#ifdef HAVE_IPV6
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
case NEXTHOP_TYPE_IPV6_IFNAME:
/* Only BGP supports IPv4 prefix with IPv6 NH, so kill this */
if (p->family == AF_INET)
stream_put_in_addr(s, &dummy_nh.gate.ipv4);
else
stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
break;
#endif
default:
if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD
|| cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL)
{
struct in_addr empty;
memset (&empty, 0, sizeof (struct in_addr));
stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
}
else
{
struct in6_addr empty;
memset (&empty, 0, sizeof (struct in6_addr));
stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
}
}
/* Interface index. */
stream_putc (s, 1);
stream_putl (s, nexthop->ifindex);
break;
}
2002-12-13 21:15:29 +01:00
}
/* Metric */
if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD || cmd == ZEBRA_REDISTRIBUTE_IPV6_ADD)
{
SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
stream_putc (s, rib->distance);
SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
stream_putl (s, rib->metric);
/* tag */
if (rib->tag)
{
SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
stream_putw(s, rib->tag);
}
}
/* write real message flags value */
stream_putc_at (s, messmark, zapi_flags);
/* Write next-hop number */
if (nhnummark)
stream_putc_at (s, nhnummark, nhnum);
2002-12-13 21:15:29 +01:00
/* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s));
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return zebra_server_send_message(client);
2002-12-13 21:15:29 +01:00
}
#ifdef HAVE_IPV6
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr,
vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
struct stream *s;
struct rib *rib;
unsigned long nump;
u_char num;
struct nexthop *nexthop;
/* Lookup nexthop. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
rib = rib_match_ipv6 (addr, vrf_id);
2002-12-13 21:15:29 +01:00
/* Get output stream. */
s = client->obuf;
stream_reset (s);
/* Fill in result. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP, vrf_id);
2002-12-13 21:15:29 +01:00
stream_put (s, &addr, 16);
if (rib)
{
stream_putl (s, rib->metric);
num = 0;
nump = stream_get_endp(s);
2002-12-13 21:15:29 +01:00
stream_putc (s, 0);
/* Only non-recursive routes are elegible to resolve nexthop we
* are looking up. Therefore, we will just iterate over the top
* chain of nexthops. */
2002-12-13 21:15:29 +01:00
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
{
stream_putc (s, nexthop->type);
switch (nexthop->type)
{
case ZEBRA_NEXTHOP_IPV6:
stream_put (s, &nexthop->gate.ipv6, 16);
break;
case ZEBRA_NEXTHOP_IPV6_IFINDEX:
case ZEBRA_NEXTHOP_IPV6_IFNAME:
stream_put (s, &nexthop->gate.ipv6, 16);
stream_putl (s, nexthop->ifindex);
break;
case ZEBRA_NEXTHOP_IFINDEX:
case ZEBRA_NEXTHOP_IFNAME:
stream_putl (s, nexthop->ifindex);
break;
default:
/* do nothing */
break;
2002-12-13 21:15:29 +01:00
}
num++;
}
stream_putc_at (s, nump, num);
}
else
{
stream_putl (s, 0);
stream_putc (s, 0);
}
stream_putw_at (s, 0, stream_get_endp (s));
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return zebra_server_send_message(client);
2002-12-13 21:15:29 +01:00
}
#endif /* HAVE_IPV6 */
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr,
vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
struct stream *s;
struct rib *rib;
unsigned long nump;
u_char num;
struct nexthop *nexthop;
/* Lookup nexthop. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
rib = rib_match_ipv4 (addr, vrf_id);
2002-12-13 21:15:29 +01:00
/* Get output stream. */
s = client->obuf;
stream_reset (s);
/* Fill in result. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP, vrf_id);
2002-12-13 21:15:29 +01:00
stream_put_in_addr (s, &addr);
if (rib)
{
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
zlog_debug("%s: Matching rib entry found.", __func__);
2002-12-13 21:15:29 +01:00
stream_putl (s, rib->metric);
num = 0;
nump = stream_get_endp(s);
2002-12-13 21:15:29 +01:00
stream_putc (s, 0);
/* Only non-recursive routes are elegible to resolve the nexthop we
* are looking up. Therefore, we will just iterate over the top
* chain of nexthops. */
2002-12-13 21:15:29 +01:00
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
{
stream_putc (s, nexthop->type);
switch (nexthop->type)
{
case ZEBRA_NEXTHOP_IPV4:
stream_put_in_addr (s, &nexthop->gate.ipv4);
break;
case ZEBRA_NEXTHOP_IPV4_IFINDEX:
stream_put_in_addr (s, &nexthop->gate.ipv4);
stream_putl (s, nexthop->ifindex);
break;
2002-12-13 21:15:29 +01:00
case ZEBRA_NEXTHOP_IFINDEX:
case ZEBRA_NEXTHOP_IFNAME:
stream_putl (s, nexthop->ifindex);
break;
default:
/* do nothing */
break;
2002-12-13 21:15:29 +01:00
}
num++;
}
stream_putc_at (s, nump, num);
}
else
{
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
zlog_debug("%s: No matching rib entry found.", __func__);
2002-12-13 21:15:29 +01:00
stream_putl (s, 0);
stream_putc (s, 0);
}
stream_putw_at (s, 0, stream_get_endp (s));
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return zebra_server_send_message(client);
2002-12-13 21:15:29 +01:00
}
/* Nexthop register */
static int
zserv_rnh_register (struct zserv *client, int sock, u_short length,
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
rnh_type_t type, vrf_id_t vrf_id)
{
struct rnh *rnh;
struct stream *s;
struct prefix p;
u_short l = 0;
u_char flags = 0;
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug("rnh_register msg from client %s: length=%d, type=%s\n",
zebra_route_string(client->proto), length,
(type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route");
s = client->ibuf;
client->nh_reg_time = quagga_time(NULL);
while (l < length)
{
flags = stream_getc(s);
p.family = stream_getw(s);
p.prefixlen = stream_getc(s);
l += 4;
if (p.family == AF_INET)
{
p.u.prefix4.s_addr = stream_get_ipv4(s);
l += IPV4_MAX_BYTELEN;
}
else if (p.family == AF_INET6)
{
stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
l += IPV6_MAX_BYTELEN;
}
else
{
zlog_err("rnh_register: Received unknown family type %d\n",
p.family);
return -1;
}
rnh = zebra_add_rnh(&p, 0, type);
if (type == RNH_NEXTHOP_TYPE)
{
if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
}
else if (type == RNH_IMPORT_CHECK_TYPE)
{
if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH))
SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH))
UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
}
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zebra_add_rnh_client(rnh, client, type, vrf_id);
/* Anything not AF_INET/INET6 has been filtered out above */
zebra_evaluate_rnh(0, p.family, 1, type, &p);
}
return 0;
}
/* Nexthop register */
static int
zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
rnh_type_t type)
{
struct rnh *rnh;
struct stream *s;
struct prefix p;
u_short l = 0;
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug("rnh_unregister msg from client %s: length=%d\n",
zebra_route_string(client->proto), length);
s = client->ibuf;
while (l < length)
{
(void)stream_getc(s); //Connected or not. Not used in this function
p.family = stream_getw(s);
p.prefixlen = stream_getc(s);
l += 4;
if (p.family == AF_INET)
{
p.u.prefix4.s_addr = stream_get_ipv4(s);
l += IPV4_MAX_BYTELEN;
}
else if (p.family == AF_INET6)
{
stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
l += IPV6_MAX_BYTELEN;
}
else
{
zlog_err("rnh_register: Received unknown family type %d\n",
p.family);
return -1;
}
rnh = zebra_lookup_rnh(&p, 0, type);
if (rnh)
{
client->nh_dereg_time = quagga_time(NULL);
zebra_remove_rnh_client(rnh, client, type);
}
}
return 0;
}
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p,
vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
struct stream *s;
struct rib *rib;
unsigned long nump;
u_char num;
struct nexthop *nexthop;
/* Lookup nexthop. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
rib = rib_lookup_ipv4 (p, vrf_id);
2002-12-13 21:15:29 +01:00
/* Get output stream. */
s = client->obuf;
stream_reset (s);
/* Fill in result. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP, vrf_id);
2002-12-13 21:15:29 +01:00
stream_put_in_addr (s, &p->prefix);
if (rib)
{
stream_putl (s, rib->metric);
num = 0;
nump = stream_get_endp(s);
2002-12-13 21:15:29 +01:00
stream_putc (s, 0);
for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
|| nexthop_has_fib_child(nexthop))
2002-12-13 21:15:29 +01:00
{
stream_putc (s, nexthop->type);
switch (nexthop->type)
{
case ZEBRA_NEXTHOP_IPV4:
stream_put_in_addr (s, &nexthop->gate.ipv4);
break;
case ZEBRA_NEXTHOP_IPV4_IFINDEX:
stream_put_in_addr (s, &nexthop->gate.ipv4);
stream_putl (s, nexthop->ifindex);
break;
2002-12-13 21:15:29 +01:00
case ZEBRA_NEXTHOP_IFINDEX:
case ZEBRA_NEXTHOP_IFNAME:
stream_putl (s, nexthop->ifindex);
break;
default:
/* do nothing */
break;
2002-12-13 21:15:29 +01:00
}
num++;
}
stream_putc_at (s, nump, num);
}
else
{
stream_putl (s, 0);
stream_putc (s, 0);
}
stream_putw_at (s, 0, stream_get_endp (s));
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return zebra_server_send_message(client);
2002-12-13 21:15:29 +01:00
}
2004-10-03 20:18:34 +02:00
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
int
zsend_router_id_update (struct zserv *client, struct prefix *p,
vrf_id_t vrf_id)
2004-10-03 20:18:34 +02:00
{
struct stream *s;
int blen;
/* Check this client need interface information. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
if (! vrf_bitmap_check (client->ridinfo, vrf_id))
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2004-10-03 20:18:34 +02:00
s = client->obuf;
stream_reset (s);
/* Message type. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
2004-10-03 20:18:34 +02:00
/* Prefix information. */
stream_putc (s, p->family);
blen = prefix_blen (p);
stream_put (s, &p->u.prefix, blen);
stream_putc (s, p->prefixlen);
/* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s));
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return zebra_server_send_message(client);
2004-10-03 20:18:34 +02:00
}
2002-12-13 21:15:29 +01:00
/* Register zebra server interface information. Send current all
interface and address information. */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
struct listnode *ifnode, *ifnnode;
struct listnode *cnode, *cnnode;
2002-12-13 21:15:29 +01:00
struct interface *ifp;
struct connected *c;
struct nbr_connected *nc;
2002-12-13 21:15:29 +01:00
/* Interface information is needed. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
vrf_bitmap_set (client->ifinfo, vrf_id);
2002-12-13 21:15:29 +01:00
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
for (ALL_LIST_ELEMENTS (vrf_iflist (vrf_id), ifnode, ifnnode, ifp))
2002-12-13 21:15:29 +01:00
{
/* Skip pseudo interface. */
if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
continue;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
if (zsend_interface_add (client, ifp) < 0)
return -1;
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
2002-12-13 21:15:29 +01:00
{
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
(zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
ifp, c) < 0))
return -1;
2002-12-13 21:15:29 +01:00
}
for (ALL_LIST_ELEMENTS (ifp->nbr_connected, cnode, cnnode, nc))
{
if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client,
ifp, nc) < 0)
return -1;
}
2002-12-13 21:15:29 +01:00
}
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
}
/* Unregister zebra server interface information. */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_interface_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
vrf_bitmap_unset (client->ifinfo, vrf_id);
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
}
void
zserv_nexthop_num_warn (const char *caller, const struct prefix *p, const u_char nexthop_num)
{
if ((MULTIPATH_NUM != 0) && (nexthop_num > MULTIPATH_NUM))
{
char buff[80];
prefix2str(p, buff, 80);
zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d",
caller, buff, nexthop_num, MULTIPATH_NUM);
}
}
2002-12-13 21:15:29 +01:00
/* This function support multiple nexthop. */
/*
* Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and
* add kernel route.
*/
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
int i;
struct rib *rib;
struct prefix_ipv4 p;
u_char message;
struct in_addr nexthop;
u_char nexthop_num;
u_char nexthop_type;
struct stream *s;
unsigned int ifindex;
u_char ifname_len;
safi_t safi;
int ret;
2002-12-13 21:15:29 +01:00
/* Get input stream. */
s = client->ibuf;
/* Allocate new rib. */
2005-04-28 Paul Jakma <paul.jakma@sun.com> * rib.h: (struct rib) Add lock field for refcounting. * zserv.h: (struct zebra_t) Add a ribq workqueue to the zebra 'master' struct. * zserv.c: (zread_ipv4_add) XMALLOC then memset should be XCALLOC. * zebra_rib.c: Clean up refcounting of route_node, make struct rib refcounted and convert rib_process to work-queue. In general, rib's should be rib_addnode'd and delnode'd to route_nodes, and these symmetrical functions will manage the locking of referenced route_node and freeing of struct rib - rather than having users manage each seperately - with much scope for bugs.. (newrib_free) removed and replaced with rib_lock (rib_lock) new function, check state of lock and increment. (rib_unlock) new function, check lock state and decrement. Free struct rib if refcount hits 0, freeing struct nexthop's, as newrib_free did. (rib_addnode) Add RIB to route_node, locking both. (rib_delnode) Delete RIB from route_node, unlocking each. (rib_process) Converted to a work-queue work function. Functional changes are minimal, just arguments, comments and whitespace. (rib_queue_add_qnode) Helper function to setup a ribq item. (rib_queue_add) Helper function, same arguments as old rib_process, to replace in callers of rib_process. (rib_queue_qnode_del) ribq deconstructor. (rib_queue_init) Create the ribq. (rib_init) call rib_queue_init. (remainder) Sanitise refcounting of route_node's. Convert to rib_queue_add, rib_addnode and rib_delnode. Change XMALLOC/memset to XCALLOC. Remove calls to nexthop_delete and nexthop_free.
2005-04-28 19:35:14 +02:00
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2002-12-13 21:15:29 +01:00
/* Type, flags, message. */
rib->type = stream_getc (s);
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
rib->instance = stream_getw (s);
2002-12-13 21:15:29 +01:00
rib->flags = stream_getc (s);
message = stream_getc (s);
safi = stream_getw (s);
2002-12-13 21:15:29 +01:00
rib->uptime = time (NULL);
/* IPv4 prefix. */
memset (&p, 0, sizeof (struct prefix_ipv4));
p.family = AF_INET;
p.prefixlen = stream_getc (s);
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
/* VRF ID */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
rib->vrf_id = vrf_id;
2002-12-13 21:15:29 +01:00
/* Nexthop parse. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
{
nexthop_num = stream_getc (s);
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
2002-12-13 21:15:29 +01:00
for (i = 0; i < nexthop_num; i++)
{
nexthop_type = stream_getc (s);
switch (nexthop_type)
{
case ZEBRA_NEXTHOP_IFINDEX:
ifindex = stream_getl (s);
nexthop_ifindex_add (rib, ifindex);
break;
case ZEBRA_NEXTHOP_IFNAME:
ifname_len = stream_getc (s);
stream_forward_getp (s, ifname_len);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_NEXTHOP_IPV4:
nexthop.s_addr = stream_get_ipv4 (s);
[zebra] Routemap support on received routes, with 'set src' command (linux) 2007-05-01 David L Stevens <dlstevens@us.ibm.com> * (general) These changes collectively add route-map and prefix-list support to zebra and fix a bug in "show route-map" (with no argument). * doc/main.texi: added route-map, prefix-list, ip protocol and set src documentation * lib/command.h: added PROTOCOL_NODE type * lib/log.c: (proto_name2num) new function, protocol name to number translation. * lib/routemap.c: (vty_show_route_map) fixed "show route-map" without route-map name * lib/routemap.h: added RMAP_ZEBRA type * lib/zebra.h: added proto_name2num() prototype * vtysh/extract.pl.in: added VTYSH_ZEBRA flag for route-map and plist * vtysh/Makefile.am: added zebra_routemap.c * vtysh/vtysh.h: added VTYSH_ZEBRA flag to VTYSH_RMAP * zebra/connected.c: (connected_up_ipv4) added src preference argument to rib_add_ipv4() * zebra/kernel_socket.c: (rtm_read) ditto * zebra/main.c: added prefix list initialization * zebra/Makefile.am: added zebra_routemap.c source file * zebra/rib.h: added generic address union "g_addr" and use in existing places that had an explicit union. Added "src" to struct nexthop. Added preferred src arg to nexthop_ipv4_add and rib_add_ipv4. * zebra/rt_netlink.c: (netlink_routing_table) set preferred source on netlink messages. (netlink_route_change) ditto (netlink_route_multipath) ditto. * zebra/rtread_getmsg.c: (handle_route_entry) added (NULL) src to rib_add_ipv4() call. * zebra/rtread_proc.c: (proc_route_read) ditto * zebra/zebra_rib.c: (nexthop_ipv4_add) add src argument. (nexthop_ipv4_ifindex_add) ditto (rib_add_ipv4) ditto (nexthop_active_check) Add route-map processing. * zebra/zebra_routemap.c: new file for zebra route-map commands. * zebra/zebra_vty.c: (ip_protocol_cmd) Apply route-map to protocol (vty_show_ip_route_detail) added "src" printing (vty_show_ip_route) ditto (show_ip_protocol_cmd) new command, list routemaps. (config_write_protocol) write out routemap protocl config. (zebra_vty_init) Install the new routemap protocol commands. * zebra/zserv.c: (zread_ipv4_add) added (NULL) src arg (zebra_init) init zebra route-maps. * zebra/zserv.h: add zebra_route_map_init
2007-05-02 18:05:35 +02:00
nexthop_ipv4_add (rib, &nexthop, NULL);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_NEXTHOP_IPV4_IFINDEX:
nexthop.s_addr = stream_get_ipv4 (s);
ifindex = stream_getl (s);
nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
break;
2002-12-13 21:15:29 +01:00
case ZEBRA_NEXTHOP_IPV6:
stream_forward_getp (s, IPV6_MAX_BYTELEN);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_NEXTHOP_BLACKHOLE:
nexthop_blackhole_add (rib);
break;
2015-05-20 02:58:13 +02:00
case ZEBRA_NEXTHOP_IPV4_ONLINK:
nexthop.s_addr = stream_get_ipv4 (s);
ifindex = stream_getl (s);
nexthop_ipv4_ifindex_ol_add (rib, &nexthop, NULL, ifindex);
break;
}
2002-12-13 21:15:29 +01:00
}
}
/* Distance. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
rib->distance = stream_getc (s);
/* Metric. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
rib->metric = stream_getl (s);
/* Tag */
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
rib->tag = stream_getw (s);
else
rib->tag = 0;
/* Table */
rib->table=zebrad.rtm_table_default;
ret = rib_add_ipv4_multipath (&p, rib, safi);
/* Stats */
if (ret > 0)
client->v4_route_add_cnt++;
else if (ret < 0)
client->v4_route_upd8_cnt++;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
}
/* Zebra server IPv4 prefix delete function. */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
int i;
struct stream *s;
struct zapi_ipv4 api;
struct in_addr nexthop, *nexthop_p;
2002-12-13 21:15:29 +01:00
unsigned long ifindex;
struct prefix_ipv4 p;
u_char nexthop_num;
u_char nexthop_type;
u_char ifname_len;
s = client->ibuf;
ifindex = 0;
nexthop.s_addr = 0;
nexthop_p = NULL;
2002-12-13 21:15:29 +01:00
/* Type, flags, message. */
api.type = stream_getc (s);
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 (s);
2002-12-13 21:15:29 +01:00
api.flags = stream_getc (s);
api.message = stream_getc (s);
api.safi = stream_getw (s);
2002-12-13 21:15:29 +01:00
/* IPv4 prefix. */
memset (&p, 0, sizeof (struct prefix_ipv4));
p.family = AF_INET;
p.prefixlen = stream_getc (s);
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
nexthop_num = stream_getc (s);
for (i = 0; i < nexthop_num; i++)
{
nexthop_type = stream_getc (s);
switch (nexthop_type)
{
case ZEBRA_NEXTHOP_IFINDEX:
ifindex = stream_getl (s);
break;
case ZEBRA_NEXTHOP_IFNAME:
ifname_len = stream_getc (s);
stream_forward_getp (s, ifname_len);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_NEXTHOP_IPV4:
nexthop.s_addr = stream_get_ipv4 (s);
nexthop_p = &nexthop;
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_NEXTHOP_IPV4_IFINDEX:
nexthop.s_addr = stream_get_ipv4 (s);
nexthop_p = &nexthop;
ifindex = stream_getl (s);
break;
2002-12-13 21:15:29 +01:00
case ZEBRA_NEXTHOP_IPV6:
stream_forward_getp (s, IPV6_MAX_BYTELEN);
2002-12-13 21:15:29 +01:00
break;
}
}
}
/* Distance. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
api.distance = stream_getc (s);
else
api.distance = 0;
/* Metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
api.metric = stream_getl (s);
else
api.metric = 0;
/* tag */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
api.tag = stream_getw (s);
else
api.tag = 0;
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
rib_delete_ipv4 (api.type, api.instance, api.flags, &p, nexthop_p, ifindex,
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
vrf_id, client->rtm_table, api.safi);
client->v4_route_del_cnt++;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
}
/* Nexthop lookup for IPv4. */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv4_nexthop_lookup (struct zserv *client, u_short length,
vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
struct in_addr addr;
char buf[BUFSIZ];
2002-12-13 21:15:29 +01:00
addr.s_addr = stream_get_ipv4 (client->ibuf);
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
zlog_debug("%s: looking up %s", __func__,
inet_ntop (AF_INET, &addr, buf, BUFSIZ));
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
return zsend_ipv4_nexthop_lookup (client, addr, vrf_id);
2002-12-13 21:15:29 +01:00
}
/* Nexthop lookup for IPv4. */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv4_import_lookup (struct zserv *client, u_short length,
vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
struct prefix_ipv4 p;
p.family = AF_INET;
p.prefixlen = stream_getc (client->ibuf);
p.prefix.s_addr = stream_get_ipv4 (client->ibuf);
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
return zsend_ipv4_import_lookup (client, &p, vrf_id);
2002-12-13 21:15:29 +01:00
}
#ifdef HAVE_IPV6
/* Zebra server IPv6 prefix add function. */
static int
zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length)
{
int i;
struct stream *s;
struct in6_addr nexthop;
struct rib *rib;
u_char message;
u_char nexthop_num;
u_char nexthop_type;
unsigned long ifindex;
struct prefix_ipv4 p;
safi_t safi;
static struct in6_addr nexthops[MULTIPATH_NUM];
static unsigned int ifindices[MULTIPATH_NUM];
int ret;
/* Get input stream. */
s = client->ibuf;
ifindex = 0;
memset (&nexthop, 0, sizeof (struct in6_addr));
/* Allocate new rib. */
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
/* Type, flags, message. */
rib->type = stream_getc (s);
rib->instance = stream_getw (s);
rib->flags = stream_getc (s);
message = stream_getc (s);
safi = stream_getw (s);
rib->uptime = time (NULL);
/* IPv4 prefix. */
memset (&p, 0, sizeof (struct prefix_ipv4));
p.family = AF_INET;
p.prefixlen = stream_getc (s);
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
/* We need to give nh-addr, nh-ifindex with the same next-hop object
* to the rib to ensure that IPv6 multipathing works; need to coalesce
* these. Clients should send the same number of paired set of
* next-hop-addr/next-hop-ifindices. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
{
int nh_count = 0;
int if_count = 0;
int max_nh_if = 0;
nexthop_num = stream_getc (s);
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
for (i = 0; i < nexthop_num; i++)
{
nexthop_type = stream_getc (s);
switch (nexthop_type)
{
case ZEBRA_NEXTHOP_IPV6:
stream_get (&nexthop, s, 16);
if (nh_count < MULTIPATH_NUM) {
nexthops[nh_count++] = nexthop;
}
break;
case ZEBRA_NEXTHOP_IFINDEX:
if (if_count < MULTIPATH_NUM) {
ifindices[if_count++] = stream_getl (s);
}
break;
case ZEBRA_NEXTHOP_BLACKHOLE:
nexthop_blackhole_add (rib);
break;
}
}
max_nh_if = (nh_count > if_count) ? nh_count : if_count;
for (i = 0; i < max_nh_if; i++)
{
if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
if ((i < if_count) && ifindices[i]) {
nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
}
else {
nexthop_ipv6_add (rib, &nexthops[i]);
}
}
else {
if ((i < if_count) && ifindices[i]) {
nexthop_ifindex_add (rib, ifindices[i]);
}
}
}
}
/* Distance. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
rib->distance = stream_getc (s);
/* Metric. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
rib->metric = stream_getl (s);
/* Tag */
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
rib->tag = stream_getw (s);
else
rib->tag = 0;
/* Table */
rib->table=zebrad.rtm_table_default;
ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
/* Stats */
if (ret > 0)
client->v4_route_add_cnt++;
else if (ret < 0)
client->v4_route_upd8_cnt++;
return 0;
}
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
int i;
struct stream *s;
struct in6_addr nexthop;
struct rib *rib;
u_char message;
u_char nexthop_num;
u_char nexthop_type;
2002-12-13 21:15:29 +01:00
unsigned long ifindex;
struct prefix_ipv6 p;
safi_t safi;
static struct in6_addr nexthops[MULTIPATH_NUM];
static unsigned int ifindices[MULTIPATH_NUM];
int ret;
/* Get input stream. */
2002-12-13 21:15:29 +01:00
s = client->ibuf;
2002-12-13 21:15:29 +01:00
ifindex = 0;
memset (&nexthop, 0, sizeof (struct in6_addr));
/* Allocate new rib. */
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
2002-12-13 21:15:29 +01:00
/* Type, flags, message. */
rib->type = stream_getc (s);
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
rib->instance = stream_getw (s);
rib->flags = stream_getc (s);
message = stream_getc (s);
safi = stream_getw (s);
rib->uptime = time (NULL);
2002-12-13 21:15:29 +01:00
/* IPv6 prefix. */
2002-12-13 21:15:29 +01:00
memset (&p, 0, sizeof (struct prefix_ipv6));
p.family = AF_INET6;
p.prefixlen = stream_getc (s);
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
/* We need to give nh-addr, nh-ifindex with the same next-hop object
* to the rib to ensure that IPv6 multipathing works; need to coalesce
* these. Clients should send the same number of paired set of
* next-hop-addr/next-hop-ifindices. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
2002-12-13 21:15:29 +01:00
{
int nh_count = 0;
int if_count = 0;
int max_nh_if = 0;
2002-12-13 21:15:29 +01:00
nexthop_num = stream_getc (s);
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
for (i = 0; i < nexthop_num; i++)
2002-12-13 21:15:29 +01:00
{
nexthop_type = stream_getc (s);
switch (nexthop_type)
{
case ZEBRA_NEXTHOP_IPV6:
stream_get (&nexthop, s, 16);
if (nh_count < MULTIPATH_NUM) {
nexthops[nh_count++] = nexthop;
}
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_NEXTHOP_IFINDEX:
if (if_count < MULTIPATH_NUM) {
ifindices[if_count++] = stream_getl (s);
}
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_NEXTHOP_BLACKHOLE:
nexthop_blackhole_add (rib);
break;
2002-12-13 21:15:29 +01:00
}
}
max_nh_if = (nh_count > if_count) ? nh_count : if_count;
for (i = 0; i < max_nh_if; i++)
{
if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) {
if ((i < if_count) && ifindices[i])
nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
else
nexthop_ipv6_add (rib, &nexthops[i]);
}
else {
if ((i < if_count) && ifindices[i])
nexthop_ifindex_add (rib, ifindices[i]);
}
}
2002-12-13 21:15:29 +01:00
}
/* Distance. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
rib->distance = stream_getc (s);
2002-12-13 21:15:29 +01:00
/* Metric. */
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
rib->metric = stream_getl (s);
2002-12-13 21:15:29 +01:00
/* Tag */
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
rib->tag = stream_getw (s);
else
rib->tag = 0;
/* Table */
rib->table=zebrad.rtm_table_default;
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
rib->vrf_id = vrf_id;
ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
/* Stats */
if (ret > 0)
client->v6_route_add_cnt++;
else if (ret < 0)
client->v6_route_upd8_cnt++;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
}
/* Zebra server IPv6 prefix delete function. */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv6_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
int i;
struct stream *s;
struct zapi_ipv6 api;
struct in6_addr nexthop;
unsigned long ifindex;
struct prefix_ipv6 p;
s = client->ibuf;
ifindex = 0;
memset (&nexthop, 0, sizeof (struct in6_addr));
/* Type, flags, message. */
api.type = stream_getc (s);
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 (s);
2002-12-13 21:15:29 +01:00
api.flags = stream_getc (s);
api.message = stream_getc (s);
api.safi = stream_getw (s);
2002-12-13 21:15:29 +01:00
/* IPv4 prefix. */
memset (&p, 0, sizeof (struct prefix_ipv6));
p.family = AF_INET6;
p.prefixlen = stream_getc (s);
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
/* Nexthop, ifindex, distance, metric. */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
{
u_char nexthop_type;
api.nexthop_num = stream_getc (s);
for (i = 0; i < api.nexthop_num; i++)
{
nexthop_type = stream_getc (s);
switch (nexthop_type)
{
case ZEBRA_NEXTHOP_IPV6:
stream_get (&nexthop, s, 16);
break;
case ZEBRA_NEXTHOP_IFINDEX:
ifindex = stream_getl (s);
break;
}
}
}
/* Distance. */
2002-12-13 21:15:29 +01:00
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
api.distance = stream_getc (s);
else
api.distance = 0;
/* Metric. */
2002-12-13 21:15:29 +01:00
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
api.metric = stream_getl (s);
else
api.metric = 0;
/* tag */
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
api.tag = stream_getw (s);
else
api.tag = 0;
2002-12-13 21:15:29 +01:00
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, NULL, ifindex,
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
vrf_id, client->rtm_table, api.safi);
2002-12-13 21:15:29 +01:00
else
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, &nexthop, ifindex,
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
vrf_id, client->rtm_table, api.safi);
client->v6_route_del_cnt++;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2002-12-13 21:15:29 +01:00
}
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv6_nexthop_lookup (struct zserv *client, u_short length,
vrf_id_t vrf_id)
2002-12-13 21:15:29 +01:00
{
struct in6_addr addr;
char buf[BUFSIZ];
stream_get (&addr, client->ibuf, 16);
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
zlog_debug("%s: looking up %s", __func__,
inet_ntop (AF_INET6, &addr, buf, BUFSIZ));
2002-12-13 21:15:29 +01:00
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
return zsend_ipv6_nexthop_lookup (client, &addr, vrf_id);
2002-12-13 21:15:29 +01:00
}
#endif /* HAVE_IPV6 */
2004-10-03 20:18:34 +02:00
/* Register zebra server router-id information. Send current router-id */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_router_id_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
2004-10-03 20:18:34 +02:00
{
struct prefix p;
/* Router-id information is needed. */
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
vrf_bitmap_set (client->ridinfo, vrf_id);
2004-10-03 20:18:34 +02:00
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
router_id_get (&p, vrf_id);
2004-10-03 20:18:34 +02:00
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
return zsend_router_id_update (client, &p, vrf_id);
2004-10-03 20:18:34 +02:00
}
/* Unregister zebra server router-id information. */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_router_id_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
2004-10-03 20:18:34 +02:00
{
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
vrf_bitmap_unset (client->ridinfo, vrf_id);
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
return 0;
2004-10-03 20:18:34 +02:00
}
/* Tie up route-type and client->sock */
static void
zread_hello (struct zserv *client)
{
/* type of protocol (lib/zebra.h) */
u_char proto;
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
u_short instance;
proto = stream_getc (client->ibuf);
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_getw (client->ibuf);
/* accept only dynamic routing protocols */
if ((proto < ZEBRA_ROUTE_MAX)
&& (proto > ZEBRA_ROUTE_STATIC))
{
zlog_notice ("client %d says hello and bids fair to announce only %s routes",
client->sock, zebra_route_string(proto));
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
if (instance)
zlog_notice ("client protocol instance %d", instance);
client->proto = proto;
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
client->instance = instance;
}
}
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
/* Unregister all information in a VRF. */
static int
zread_vrf_unregister (struct zserv *client, u_short length, vrf_id_t vrf_id)
{
int i;
afi_t afi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
vrf_bitmap_unset (client->redist[afi][i], vrf_id);
vrf_bitmap_unset (client->redist_default, vrf_id);
vrf_bitmap_unset (client->ifinfo, vrf_id);
vrf_bitmap_unset (client->ridinfo, vrf_id);
return 0;
}
2002-12-13 21:15:29 +01:00
/* Close zebra client. */
static void
2002-12-13 21:15:29 +01:00
zebra_client_close (struct zserv *client)
{
zebra_cleanup_rnh_client(0, AF_INET, client, RNH_NEXTHOP_TYPE);
zebra_cleanup_rnh_client(0, AF_INET6, client, RNH_NEXTHOP_TYPE);
zebra_cleanup_rnh_client(0, AF_INET, client, RNH_IMPORT_CHECK_TYPE);
zebra_cleanup_rnh_client(0, AF_INET6, client, RNH_IMPORT_CHECK_TYPE);
2002-12-13 21:15:29 +01:00
/* Close file descriptor. */
if (client->sock)
{
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
unsigned long nroutes;
2002-12-13 21:15:29 +01:00
close (client->sock);
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
nroutes = rib_score_proto (client->proto, client->instance);
zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
client->sock, nroutes, zebra_route_string (client->proto));
2002-12-13 21:15:29 +01:00
client->sock = -1;
}
/* Free stream buffers. */
if (client->ibuf)
stream_free (client->ibuf);
if (client->obuf)
stream_free (client->obuf);
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
if (client->wb)
buffer_free(client->wb);
2002-12-13 21:15:29 +01:00
/* Release threads. */
if (client->t_read)
thread_cancel (client->t_read);
if (client->t_write)
thread_cancel (client->t_write);
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
if (client->t_suicide)
thread_cancel (client->t_suicide);
2002-12-13 21:15:29 +01:00
/* Free client structure. */
listnode_delete (zebrad.client_list, client);
2002-12-13 21:15:29 +01:00
XFREE (0, client);
}
/* Make new client. */
static void
2002-12-13 21:15:29 +01:00
zebra_client_create (int sock)
{
struct zserv *client;
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
int i;
afi_t afi;
2002-12-13 21:15:29 +01:00
client = XCALLOC (0, sizeof (struct zserv));
/* Make client input/output buffer. */
client->sock = sock;
client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
client->wb = buffer_new(0);
2002-12-13 21:15:29 +01:00
/* Set table number. */
client->rtm_table = zebrad.rtm_table_default;
2002-12-13 21:15:29 +01:00
client->connect_time = quagga_time(NULL);
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
/* Initialize flags */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
client->redist[afi][i] = vrf_bitmap_init ();
client->redist_default = vrf_bitmap_init ();
client->ifinfo = vrf_bitmap_init ();
client->ridinfo = vrf_bitmap_init ();
2002-12-13 21:15:29 +01:00
/* Add this client to linked list. */
listnode_add (zebrad.client_list, client);
2002-12-13 21:15:29 +01:00
/* Make new read thread. */
zebra_event (ZEBRA_READ, sock, client);
}
/* Handler of zebra service request. */
static int
2002-12-13 21:15:29 +01:00
zebra_client_read (struct thread *thread)
{
int sock;
struct zserv *client;
size_t already;
uint16_t length, command;
uint8_t marker, version;
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
vrf_id_t vrf_id;
2002-12-13 21:15:29 +01:00
/* Get thread data. Reset reading thread because I'm running. */
sock = THREAD_FD (thread);
client = THREAD_ARG (thread);
client->t_read = NULL;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
if (client->t_suicide)
2002-12-13 21:15:29 +01:00
{
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
zebra_client_close(client);
2002-12-13 21:15:29 +01:00
return -1;
}
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
/* Read length and command (if we don't have it already). */
if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE)
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
{
ssize_t nbyte;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
if (((nbyte = stream_read_try (client->ibuf, sock,
ZEBRA_HEADER_SIZE-already)) == 0) ||
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
(nbyte == -1))
{
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug ("connection closed socket [%d]", sock);
zebra_client_close (client);
return -1;
}
if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
{
/* Try again later. */
zebra_event (ZEBRA_READ, sock, client);
return 0;
}
already = ZEBRA_HEADER_SIZE;
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
}
/* Reset to read from the beginning of the incoming packet. */
stream_set_getp(client->ibuf, 0);
/* Fetch header values */
2002-12-13 21:15:29 +01:00
length = stream_getw (client->ibuf);
marker = stream_getc (client->ibuf);
version = stream_getc (client->ibuf);
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
vrf_id = stream_getw (client->ibuf);
command = stream_getw (client->ibuf);
2002-12-13 21:15:29 +01:00
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
{
zlog_err("%s: socket %d version mismatch, marker %d, version %d",
__func__, sock, marker, version);
zebra_client_close (client);
return -1;
}
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
if (length < ZEBRA_HEADER_SIZE)
2002-12-13 21:15:29 +01:00
{
zlog_warn("%s: socket %d message length %u is less than header size %d",
__func__, sock, length, ZEBRA_HEADER_SIZE);
zebra_client_close (client);
return -1;
}
if (length > STREAM_SIZE(client->ibuf))
{
zlog_warn("%s: socket %d message length %u exceeds buffer size %lu",
__func__, sock, length, (u_long)STREAM_SIZE(client->ibuf));
2002-12-13 21:15:29 +01:00
zebra_client_close (client);
return -1;
}
/* Read rest of data. */
if (already < length)
2002-12-13 21:15:29 +01:00
{
ssize_t nbyte;
if (((nbyte = stream_read_try (client->ibuf, sock,
length-already)) == 0) ||
(nbyte == -1))
2002-12-13 21:15:29 +01:00
{
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug ("connection closed [%d] when reading zebra data", sock);
2002-12-13 21:15:29 +01:00
zebra_client_close (client);
return -1;
}
if (nbyte != (ssize_t)(length-already))
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
{
/* Try again later. */
zebra_event (ZEBRA_READ, sock, client);
return 0;
}
2002-12-13 21:15:29 +01:00
}
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
length -= ZEBRA_HEADER_SIZE;
2002-12-13 21:15:29 +01:00
/* Debug packet information. */
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug ("zebra message comes from socket [%d]", sock);
2002-12-13 21:15:29 +01:00
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zlog_debug ("zebra message received [%s] %d in VRF %u",
zserv_command_string (command), length, vrf_id);
2002-12-13 21:15:29 +01:00
client->last_read_time = quagga_time(NULL);
client->last_read_cmd = command;
2002-12-13 21:15:29 +01:00
switch (command)
{
2004-10-03 20:18:34 +02:00
case ZEBRA_ROUTER_ID_ADD:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_router_id_add (client, length, vrf_id);
2004-10-03 20:18:34 +02:00
break;
case ZEBRA_ROUTER_ID_DELETE:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_router_id_delete (client, length, vrf_id);
2004-10-03 20:18:34 +02:00
break;
2002-12-13 21:15:29 +01:00
case ZEBRA_INTERFACE_ADD:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_interface_add (client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_INTERFACE_DELETE:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_interface_delete (client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_IPV4_ROUTE_ADD:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv4_add (client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_IPV4_ROUTE_DELETE:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv4_delete (client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
#ifdef HAVE_IPV6
case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD:
zread_ipv4_route_ipv6_nexthop_add (client, length);
break;
2002-12-13 21:15:29 +01:00
case ZEBRA_IPV6_ROUTE_ADD:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv6_add (client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_IPV6_ROUTE_DELETE:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv6_delete (client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
#endif /* HAVE_IPV6 */
case ZEBRA_REDISTRIBUTE_ADD:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zebra_redistribute_add (command, client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_REDISTRIBUTE_DELETE:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zebra_redistribute_delete (command, client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zebra_redistribute_default_add (command, client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zebra_redistribute_default_delete (command, client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_IPV4_NEXTHOP_LOOKUP:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv4_nexthop_lookup (client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
#ifdef HAVE_IPV6
case ZEBRA_IPV6_NEXTHOP_LOOKUP:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv6_nexthop_lookup (client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
#endif /* HAVE_IPV6 */
case ZEBRA_IPV4_IMPORT_LOOKUP:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zread_ipv4_import_lookup (client, length, vrf_id);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_HELLO:
zread_hello (client);
break;
case ZEBRA_NEXTHOP_REGISTER:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE, vrf_id);
break;
case ZEBRA_NEXTHOP_UNREGISTER:
zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE);
break;
case ZEBRA_IMPORT_ROUTE_REGISTER:
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE, vrf_id);
break;
case ZEBRA_IMPORT_ROUTE_UNREGISTER:
zserv_rnh_unregister(client, sock, length, RNH_IMPORT_CHECK_TYPE);
break;
case ZEBRA_BFD_DEST_UPDATE:
case ZEBRA_BFD_DEST_REGISTER:
zebra_ptm_bfd_dst_register(client, sock, length, command);
break;
case ZEBRA_BFD_DEST_DEREGISTER:
zebra_ptm_bfd_dst_deregister(client, sock, length);
break;
*: add VRF ID in the API message header The API messages are used by zebra to exchange the interfaces, addresses, routes and router-id information with its clients. To distinguish which VRF the information belongs to, a new field "VRF ID" is added in the message header. And hence the message version is increased to 3. * The new field "VRF ID" in the message header: Length (2 bytes) Marker (1 byte) Version (1 byte) VRF ID (2 bytes, newly added) Command (2 bytes) - Client side: - zclient_create_header() adds the VRF ID in the message header. - zclient_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the callback functions registered to the API messages. - All relative functions are appended with a new parameter "vrf_id", including all the callback functions. - "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6". Clients need to correctly set the VRF ID when using the API functions zapi_ipv4_route() and zapi_ipv6_route(). - Till now all messages sent from a client have the default VRF ID "0" in the header. - The HELLO message is special, which is used as the heart-beat of a client, and has no relation with VRF. The VRF ID in the HELLO message header will always be 0 and ignored by zebra. - Zebra side: - zserv_create_header() adds the VRF ID in the message header. - zebra_client_read() extracts and validates the VRF ID from the header, and passes the VRF ID to the functions which process the received messages. - All relative functions are appended with a new parameter "vrf_id". * Suppress the messages in a VRF which a client does not care: Some clients may not care about the information in the VRF X, and zebra should not send the messages in the VRF X to those clients. Extra flags are used to indicate which VRF is registered by a client, and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client can unregister a VRF when it does not need any information in that VRF. A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF will automatically register to that VRF. - lib/vrf: A new utility "VRF bit-map" is provided to manage the flags for VRFs, one bit per VRF ID. - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a bit-map; - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag in the given bit-map, corresponding to the given VRF ID; - Use vrf_bitmap_check() to test whether the flag, in the given bit-map and for the given VRF ID, is set. - Client side: - In "struct zclient", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] default_information These flags are extended for each VRF, and controlled by the clients themselves (or with the help of zclient_redistribute() and zclient_redistribute_default()). - Zebra side: - In "struct zserv", the following flags are changed from "u_char" to "vrf_bitmap_t": redist[ZEBRA_ROUTE_MAX] redist_default ifinfo ridinfo These flags are extended for each VRF, as the VRF registration flags. They are maintained on receiving a ZEBRA_XXX_ADD or ZEBRA_XXX_DELETE message. When sending an interface/address/route/router-id message in a VRF to a client, if the corresponding VRF registration flag is not set, this message will not be dropped by zebra. - A new function zread_vrf_unregister() is introduced to process the new command ZEBRA_VRF_UNREGISTER. All the VRF registration flags are cleared for the requested VRF. Those clients, who support only the default VRF, will never receive a message in a non-default VRF, thanks to the filter in zebra. * New callback for the event of successful connection to zebra: - zclient_start() is splitted, keeping only the code of connecting to zebra. - Now zclient_init()=>zclient_connect()=>zclient_start() operations are purely dealing with the connection to zbera. - Once zebra is successfully connected, at the end of zclient_start(), a new callback is used to inform the client about connection. - Till now, in the callback of connect-to-zebra event, all clients send messages to zebra to request the router-id/interface/routes information in the default VRF. Of corse in future the client can do anything it wants in this callback. For example, it may send requests for both default VRF and some non-default VRFs. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/zclient.h lib/zebra.h zebra/zserv.c zebra/zserv.h Conflicts: bgpd/bgp_nexthop.c bgpd/bgp_nht.c bgpd/bgp_zebra.c isisd/isis_zebra.c lib/zclient.c lib/zclient.h lib/zebra.h nhrpd/nhrp_interface.c nhrpd/nhrp_route.c nhrpd/nhrpd.h ospf6d/ospf6_zebra.c ospf6d/ospf6_zebra.h ospfd/ospf_vty.c ospfd/ospf_zebra.c pimd/pim_zebra.c pimd/pim_zlookup.c ripd/rip_zebra.c ripngd/ripng_zebra.c zebra/redistribute.c zebra/rt_netlink.c zebra/zebra_rnh.c zebra/zebra_rnh.h zebra/zserv.c zebra/zserv.h
2014-10-16 03:52:36 +02:00
case ZEBRA_VRF_UNREGISTER:
zread_vrf_unregister (client, length, vrf_id);
break;
2002-12-13 21:15:29 +01:00
default:
zlog_info ("Zebra received unknown command %d", command);
break;
}
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
if (client->t_suicide)
{
/* No need to wait for thread callback, just kill immediately. */
zebra_client_close(client);
return -1;
}
2002-12-13 21:15:29 +01:00
stream_reset (client->ibuf);
zebra_event (ZEBRA_READ, sock, client);
return 0;
}
/* Accept code of zebra server socket. */
static int
2002-12-13 21:15:29 +01:00
zebra_accept (struct thread *thread)
{
int accept_sock;
int client_sock;
struct sockaddr_in client;
socklen_t len;
accept_sock = THREAD_FD (thread);
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
/* Reregister myself. */
zebra_event (ZEBRA_SERV, accept_sock, NULL);
2002-12-13 21:15:29 +01:00
len = sizeof (struct sockaddr_in);
client_sock = accept (accept_sock, (struct sockaddr *) &client, &len);
if (client_sock < 0)
{
zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno));
2002-12-13 21:15:29 +01:00
return -1;
}
2003-03-01 12:42:20 +01:00
/* Make client socket non-blocking. */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
set_nonblocking(client_sock);
2002-12-13 21:15:29 +01:00
/* Create new zebra client. */
zebra_client_create (client_sock);
return 0;
}
#ifdef HAVE_TCP_ZEBRA
2002-12-13 21:15:29 +01:00
/* Make zebra's server socket. */
static void
2002-12-13 21:15:29 +01:00
zebra_serv ()
{
int ret;
int accept_sock;
struct sockaddr_in addr;
accept_sock = socket (AF_INET, SOCK_STREAM, 0);
if (accept_sock < 0)
{
zlog_warn ("Can't create zserv stream socket: %s",
safe_strerror (errno));
2002-12-13 21:15:29 +01:00
zlog_warn ("zebra can't provice full functionality due to above error");
return;
}
memset (&addr, 0, sizeof (struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons (ZEBRA_PORT);
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
2002-12-13 21:15:29 +01:00
addr.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
2002-12-13 21:15:29 +01:00
addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
sockopt_reuseaddr (accept_sock);
sockopt_reuseport (accept_sock);
if ( zserv_privs.change(ZPRIVS_RAISE) )
zlog (NULL, LOG_ERR, "Can't raise privileges");
2002-12-13 21:15:29 +01:00
ret = bind (accept_sock, (struct sockaddr *)&addr,
sizeof (struct sockaddr_in));
if (ret < 0)
{
zlog_warn ("Can't bind to stream socket: %s",
safe_strerror (errno));
2002-12-13 21:15:29 +01:00
zlog_warn ("zebra can't provice full functionality due to above error");
close (accept_sock); /* Avoid sd leak. */
return;
}
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog (NULL, LOG_ERR, "Can't lower privileges");
2002-12-13 21:15:29 +01:00
ret = listen (accept_sock, 1);
if (ret < 0)
{
zlog_warn ("Can't listen to stream socket: %s",
safe_strerror (errno));
2002-12-13 21:15:29 +01:00
zlog_warn ("zebra can't provice full functionality due to above error");
close (accept_sock); /* Avoid sd leak. */
return;
}
zebra_event (ZEBRA_SERV, accept_sock, NULL);
}
#endif /* HAVE_TCP_ZEBRA */
2002-12-13 21:15:29 +01:00
/* For sockaddr_un. */
#include <sys/un.h>
/* zebra server UNIX domain socket. */
static void
zebra_serv_un (const char *path)
2002-12-13 21:15:29 +01:00
{
int ret;
int sock, len;
struct sockaddr_un serv;
mode_t old_mask;
/* First of all, unlink existing socket */
unlink (path);
/* Set umask */
old_mask = umask (0077);
/* Make UNIX domain socket. */
sock = socket (AF_UNIX, SOCK_STREAM, 0);
if (sock < 0)
{
zlog_warn ("Can't create zserv unix socket: %s",
safe_strerror (errno));
zlog_warn ("zebra can't provide full functionality due to above error");
2002-12-13 21:15:29 +01:00
return;
}
/* Make server socket. */
memset (&serv, 0, sizeof (struct sockaddr_un));
serv.sun_family = AF_UNIX;
strncpy (serv.sun_path, path, strlen (path));
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
2002-12-13 21:15:29 +01:00
len = serv.sun_len = SUN_LEN(&serv);
#else
len = sizeof (serv.sun_family) + strlen (serv.sun_path);
#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
2002-12-13 21:15:29 +01:00
ret = bind (sock, (struct sockaddr *) &serv, len);
if (ret < 0)
{
zlog_warn ("Can't bind to unix socket %s: %s",
path, safe_strerror (errno));
zlog_warn ("zebra can't provide full functionality due to above error");
2002-12-13 21:15:29 +01:00
close (sock);
return;
}
ret = listen (sock, 5);
if (ret < 0)
{
zlog_warn ("Can't listen to unix socket %s: %s",
path, safe_strerror (errno));
zlog_warn ("zebra can't provide full functionality due to above error");
2002-12-13 21:15:29 +01:00
close (sock);
return;
}
umask (old_mask);
zebra_event (ZEBRA_SERV, sock, NULL);
}
2002-12-13 21:15:29 +01:00
static void
2002-12-13 21:15:29 +01:00
zebra_event (enum event event, int sock, struct zserv *client)
{
switch (event)
{
case ZEBRA_SERV:
thread_add_read (zebrad.master, zebra_accept, client, sock);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_READ:
client->t_read =
thread_add_read (zebrad.master, zebra_client_read, client, sock);
2002-12-13 21:15:29 +01:00
break;
case ZEBRA_WRITE:
/**/
break;
}
}
#define ZEBRA_TIME_BUF 32
static char *
zserv_time_buf(time_t *time1, char *buf, int buflen)
{
struct tm *tm;
time_t now;
assert (buf != NULL);
assert (buflen >= ZEBRA_TIME_BUF);
assert (time1 != NULL);
if (!*time1)
{
snprintf(buf, buflen, "never ");
return (buf);
}
now = quagga_time(NULL);
now -= *time1;
tm = gmtime(&now);
/* Making formatted timer strings. */
#define ONE_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7
if (now < ONE_DAY_SECOND)
snprintf (buf, buflen, "%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
else if (now < ONE_WEEK_SECOND)
snprintf (buf, buflen, "%dd%02dh%02dm",
tm->tm_yday, tm->tm_hour, tm->tm_min);
else
snprintf (buf, buflen, "%02dw%dd%02dh",
tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
return buf;
}
static void
zebra_show_client_detail (struct vty *vty, struct zserv *client)
{
char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF];
char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF];
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
vty_out (vty, "Client: %s", zebra_route_string(client->proto));
if (client->instance)
vty_out (vty, " Instance: %d", client->instance);
vty_out (vty, "%s", VTY_NEWLINE);
vty_out (vty, "------------------------ %s", VTY_NEWLINE);
vty_out (vty, "FD: %d %s", client->sock, VTY_NEWLINE);
vty_out (vty, "Route Table ID: %d %s", client->rtm_table, VTY_NEWLINE);
vty_out (vty, "Connect Time: %s %s",
zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF),
VTY_NEWLINE);
if (client->nh_reg_time)
{
vty_out (vty, "Nexthop Registry Time: %s %s",
zserv_time_buf(&client->nh_reg_time, nhbuf, ZEBRA_TIME_BUF),
VTY_NEWLINE);
if (client->nh_last_upd_time)
vty_out (vty, "Nexthop Last Update Time: %s %s",
zserv_time_buf(&client->nh_last_upd_time, mbuf, ZEBRA_TIME_BUF),
VTY_NEWLINE);
else
vty_out (vty, "No Nexthop Update sent%s", VTY_NEWLINE);
}
else
vty_out (vty, "Not registered for Nexthop Updates%s", VTY_NEWLINE);
vty_out (vty, "Last Msg Rx Time: %s %s",
zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF),
VTY_NEWLINE);
vty_out (vty, "Last Msg Tx Time: %s %s",
zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF),
VTY_NEWLINE);
if (client->last_read_time)
vty_out (vty, "Last Rcvd Cmd: %s %s",
zserv_command_string(client->last_read_cmd), VTY_NEWLINE);
if (client->last_write_time)
vty_out (vty, "Last Sent Cmd: %s %s",
zserv_command_string(client->last_write_cmd), VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
vty_out (vty, "Type Add Update Del %s", VTY_NEWLINE);
vty_out (vty, "================================================== %s", VTY_NEWLINE);
vty_out (vty, "IPv4 %-12d%-12d%-12d%s", client->v4_route_add_cnt,
client->v4_route_upd8_cnt, client->v4_route_del_cnt, VTY_NEWLINE);
vty_out (vty, "IPv6 %-12d%-12d%-12d%s", client->v6_route_add_cnt,
client->v6_route_upd8_cnt, client->v6_route_del_cnt, VTY_NEWLINE);
vty_out (vty, "Redist:v4 %-12d%-12d%-12d%s", client->redist_v4_add_cnt, 0,
client->redist_v4_del_cnt, VTY_NEWLINE);
vty_out (vty, "Redist:v6 %-12d%-12d%-12d%s", client->redist_v6_add_cnt, 0,
client->redist_v6_del_cnt, VTY_NEWLINE);
vty_out (vty, "Connected %-12d%-12d%-12d%s", client->ifadd_cnt, 0,
client->ifdel_cnt, VTY_NEWLINE);
vty_out (vty, "BFD peer %-12d%-12d%-12d%s", client->bfd_peer_add_cnt,
client->bfd_peer_upd8_cnt, client->bfd_peer_del_cnt, VTY_NEWLINE);
vty_out (vty, "Interface Up Notifications: %d%s", client->ifup_cnt,
VTY_NEWLINE);
vty_out (vty, "Interface Down Notifications: %d%s", client->ifdown_cnt,
VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
return;
}
static void
zebra_show_client_brief (struct vty *vty, struct zserv *client)
{
char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF];
char wbuf[ZEBRA_TIME_BUF];
vty_out (vty, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d%s",
zebra_route_string(client->proto),
zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF),
zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF),
zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF),
client->v4_route_add_cnt+client->v4_route_upd8_cnt,
client->v4_route_del_cnt,
client->v6_route_add_cnt+client->v6_route_upd8_cnt,
client->v6_route_del_cnt, VTY_NEWLINE);
}
2002-12-13 21:15:29 +01:00
/* Display default rtm_table for all clients. */
DEFUN (show_table,
show_table_cmd,
"show table",
SHOW_STR
"default routing table to use for all clients\n")
{
vty_out (vty, "table %d%s", zebrad.rtm_table_default,
2002-12-13 21:15:29 +01:00
VTY_NEWLINE);
return CMD_SUCCESS;
}
DEFUN (config_table,
config_table_cmd,
"table TABLENO",
"Configure target kernel routing table\n"
"TABLE integer\n")
{
zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
2002-12-13 21:15:29 +01:00
return CMD_SUCCESS;
}
DEFUN (ip_forwarding,
ip_forwarding_cmd,
"ip forwarding",
IP_STR
"Turn on IP forwarding")
{
int ret;
ret = ipforward ();
if (ret == 0)
ret = ipforward_on ();
if (ret == 0)
{
vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
2002-12-13 21:15:29 +01:00
DEFUN (no_ip_forwarding,
no_ip_forwarding_cmd,
"no ip forwarding",
NO_STR
IP_STR
"Turn off IP forwarding")
{
int ret;
ret = ipforward ();
if (ret != 0)
ret = ipforward_off ();
2002-12-13 21:15:29 +01:00
if (ret != 0)
{
vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
/* This command is for debugging purpose. */
DEFUN (show_zebra_client,
show_zebra_client_cmd,
"show zebra client",
SHOW_STR
"Zebra information"
"Client information")
{
struct listnode *node;
2002-12-13 21:15:29 +01:00
struct zserv *client;
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
zebra_show_client_detail(vty, client);
return CMD_SUCCESS;
}
/* This command is for debugging purpose. */
DEFUN (show_zebra_client_summary,
show_zebra_client_summary_cmd,
"show zebra client summary",
SHOW_STR
"Zebra information brief"
"Client information brief")
{
struct listnode *node;
struct zserv *client;
vty_out (vty, "Name Connect Time Last Read Last Write IPv4 Routes IPv6 Routes %s",
VTY_NEWLINE);
vty_out (vty,"--------------------------------------------------------------------------------%s",
VTY_NEWLINE);
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
zebra_show_client_brief(vty, client);
vty_out (vty, "Routes column shows (added+updated)/deleted%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
return CMD_SUCCESS;
}
/* Table configuration write function. */
static int
2002-12-13 21:15:29 +01:00
config_write_table (struct vty *vty)
{
if (zebrad.rtm_table_default)
vty_out (vty, "table %d%s", zebrad.rtm_table_default,
2002-12-13 21:15:29 +01:00
VTY_NEWLINE);
return 0;
}
/* table node for routing tables. */
static struct cmd_node table_node =
2002-12-13 21:15:29 +01:00
{
TABLE_NODE,
"", /* This node has no interface. */
1
};
2002-12-13 21:15:29 +01:00
/* Only display ip forwarding is enabled or not. */
DEFUN (show_ip_forwarding,
show_ip_forwarding_cmd,
"show ip forwarding",
SHOW_STR
IP_STR
"IP forwarding status\n")
{
int ret;
ret = ipforward ();
if (ret == 0)
vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE);
else
vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
#ifdef HAVE_IPV6
/* Only display ipv6 forwarding is enabled or not. */
DEFUN (show_ipv6_forwarding,
show_ipv6_forwarding_cmd,
"show ipv6 forwarding",
SHOW_STR
"IPv6 information\n"
"Forwarding status\n")
{
int ret;
ret = ipforward_ipv6 ();
switch (ret)
{
case -1:
vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE);
break;
case 0:
vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
break;
case 1:
vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE);
break;
default:
vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE);
break;
}
return CMD_SUCCESS;
}
DEFUN (ipv6_forwarding,
ipv6_forwarding_cmd,
"ipv6 forwarding",
IPV6_STR
"Turn on IPv6 forwarding")
{
int ret;
ret = ipforward_ipv6 ();
if (ret == 0)
ret = ipforward_ipv6_on ();
if (ret == 0)
{
vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
2002-12-13 21:15:29 +01:00
DEFUN (no_ipv6_forwarding,
no_ipv6_forwarding_cmd,
"no ipv6 forwarding",
NO_STR
IPV6_STR
"Turn off IPv6 forwarding")
2002-12-13 21:15:29 +01:00
{
int ret;
ret = ipforward_ipv6 ();
if (ret != 0)
ret = ipforward_ipv6_off ();
2002-12-13 21:15:29 +01:00
if (ret != 0)
{
vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
#endif /* HAVE_IPV6 */
/* IPForwarding configuration write function. */
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * zserv.c: Must include network.h and buffer.h for non-blocking I/O. Remove global message_queue and t_write (need separate buffering for each client). (zebra_server_dequeue,zebra_server_enqueue) Remove functions related to old buggy buffering code. (zserv_delayed_close) New thread callback function to delete a client. (zserv_flush_data) New thread callback function to flush buffered data to client. (zebra_server_send_message) Rewritten to use buffer_write (so buffering of writes and non-blocking I/O work properly). (zsend_interface_add,zsend_interface_delete,zsend_interface_address, zsend_interface_update) Return 0 instead of -1 if !client->ifinfo (this is not really an error). Return value from zebra_server_send_message. (zsend_route_multipath,zsend_ipv4_nexthop_lookup, zsend_ipv4_import_lookup) Return value from zebra_server_send_message. (zsend_ipv6_nexthop_lookup) Fix scope to static, and return value from zebra_server_send_message. (zsend_router_id_update) Must use zebra_server_send_message instead of deprecated writen function. Return 0 instead of -1 if this client is not subscribed to router-id updates (since this is not really an error). (zread_interface_add) Change type to static int. If zsend_interface_add fails or zsend_interface_address fails, return -1 immediately (since the client has had an I/O error). (zread_interface_delete,zread_ipv4_add,zread_ipv4_delete, zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0 to indicate success. (zread_ipv4_nexthop_lookup) Return value from zsend_ipv4_nexthop_lookup. (zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup. (zebra_read_ipv6) Remove unused function. (zread_ipv6_nexthop_lookup) Return value from zsend_ipv6_nexthop_lookup. (zread_router_id_add) Return value from zsend_router_id_update. (zebra_client_close) Call buffer_free(client->wb) and thread_cancel(client->t_suicide). (zebra_client_create) Allocate client->wb using buffer_new. (zebra_client_read) Support non-blocking I/O by using stream_read_try. Use ZEBRA_HEADER_SIZE instead of 3. (zebra_accept) Fix bug: reset accept thread at top. Make client socket non-blocking using the set_nonblocking function. (config_write_forwarding) Fix scope to static. (zebra_init) Remove initialization code for old buggy write buffering. * zserv.h: Add 2 new fields to struct zserv: struct buffer *wb (to enable buffered writes with non-blocking I/), and struct thread *t_suicide to support delayed close on I/O errors. * router-id.h: Remove prototypes for zread_router_id_add and zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
static int
2002-12-13 21:15:29 +01:00
config_write_forwarding (struct vty *vty)
{
2004-10-03 20:18:34 +02:00
/* FIXME: Find better place for that. */
router_id_write (vty);
if (ipforward ())
vty_out (vty, "ip forwarding%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
#ifdef HAVE_IPV6
if (ipforward_ipv6 ())
vty_out (vty, "ipv6 forwarding%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
#endif /* HAVE_IPV6 */
vty_out (vty, "!%s", VTY_NEWLINE);
return 0;
}
/* table node for routing tables. */
static struct cmd_node forwarding_node =
2002-12-13 21:15:29 +01:00
{
FORWARDING_NODE,
"", /* This node has no interface. */
1
};
2002-12-13 21:15:29 +01:00
/* Initialisation of zebra and installation of commands. */
void
zebra_init (void)
2002-12-13 21:15:29 +01:00
{
/* Client list init. */
zebrad.client_list = list_new ();
2002-12-13 21:15:29 +01:00
/* Install configuration write function. */
install_node (&table_node, config_write_table);
install_node (&forwarding_node, config_write_forwarding);
install_element (VIEW_NODE, &show_ip_forwarding_cmd);
install_element (ENABLE_NODE, &show_ip_forwarding_cmd);
install_element (CONFIG_NODE, &ip_forwarding_cmd);
2002-12-13 21:15:29 +01:00
install_element (CONFIG_NODE, &no_ip_forwarding_cmd);
install_element (ENABLE_NODE, &show_zebra_client_cmd);
install_element (ENABLE_NODE, &show_zebra_client_summary_cmd);
2002-12-13 21:15:29 +01:00
#ifdef HAVE_NETLINK
install_element (VIEW_NODE, &show_table_cmd);
install_element (ENABLE_NODE, &show_table_cmd);
install_element (CONFIG_NODE, &config_table_cmd);
#endif /* HAVE_NETLINK */
#ifdef HAVE_IPV6
install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
2002-12-13 21:15:29 +01:00
install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
#endif /* HAVE_IPV6 */
[zebra] Routemap support on received routes, with 'set src' command (linux) 2007-05-01 David L Stevens <dlstevens@us.ibm.com> * (general) These changes collectively add route-map and prefix-list support to zebra and fix a bug in "show route-map" (with no argument). * doc/main.texi: added route-map, prefix-list, ip protocol and set src documentation * lib/command.h: added PROTOCOL_NODE type * lib/log.c: (proto_name2num) new function, protocol name to number translation. * lib/routemap.c: (vty_show_route_map) fixed "show route-map" without route-map name * lib/routemap.h: added RMAP_ZEBRA type * lib/zebra.h: added proto_name2num() prototype * vtysh/extract.pl.in: added VTYSH_ZEBRA flag for route-map and plist * vtysh/Makefile.am: added zebra_routemap.c * vtysh/vtysh.h: added VTYSH_ZEBRA flag to VTYSH_RMAP * zebra/connected.c: (connected_up_ipv4) added src preference argument to rib_add_ipv4() * zebra/kernel_socket.c: (rtm_read) ditto * zebra/main.c: added prefix list initialization * zebra/Makefile.am: added zebra_routemap.c source file * zebra/rib.h: added generic address union "g_addr" and use in existing places that had an explicit union. Added "src" to struct nexthop. Added preferred src arg to nexthop_ipv4_add and rib_add_ipv4. * zebra/rt_netlink.c: (netlink_routing_table) set preferred source on netlink messages. (netlink_route_change) ditto (netlink_route_multipath) ditto. * zebra/rtread_getmsg.c: (handle_route_entry) added (NULL) src to rib_add_ipv4() call. * zebra/rtread_proc.c: (proc_route_read) ditto * zebra/zebra_rib.c: (nexthop_ipv4_add) add src argument. (nexthop_ipv4_ifindex_add) ditto (rib_add_ipv4) ditto (nexthop_active_check) Add route-map processing. * zebra/zebra_routemap.c: new file for zebra route-map commands. * zebra/zebra_vty.c: (ip_protocol_cmd) Apply route-map to protocol (vty_show_ip_route_detail) added "src" printing (vty_show_ip_route) ditto (show_ip_protocol_cmd) new command, list routemaps. (config_write_protocol) write out routemap protocl config. (zebra_vty_init) Install the new routemap protocol commands. * zebra/zserv.c: (zread_ipv4_add) added (NULL) src arg (zebra_init) init zebra route-maps. * zebra/zserv.h: add zebra_route_map_init
2007-05-02 18:05:35 +02:00
/* Route-map */
zebra_route_map_init ();
2002-12-13 21:15:29 +01:00
}
/* Make zebra server socket, wiping any existing one (see bug #403). */
void
zebra_zserv_socket_init (char *path)
{
#ifdef HAVE_TCP_ZEBRA
zebra_serv ();
#else
zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
#endif /* HAVE_TCP_ZEBRA */
}