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"
|
2003-06-04 15:59:38 +02:00
|
|
|
#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"
|
2015-05-20 02:40:34 +02:00
|
|
|
#include "nexthop.h"
|
2015-05-22 11:40:02 +02:00
|
|
|
#include "vrf.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include "zebra/zserv.h"
|
2016-04-14 15:20:47 +02:00
|
|
|
#include "zebra/zebra_ns.h"
|
|
|
|
#include "zebra/zebra_vrf.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"
|
2015-05-20 02:40:34 +02:00
|
|
|
#include "zebra/zebra_rnh.h"
|
2015-06-11 18:19:59 +02:00
|
|
|
#include "zebra/rt_netlink.h"
|
2015-07-26 00:55:47 +02:00
|
|
|
#include "zebra/interface.h"
|
|
|
|
#include "zebra/zebra_ptm.h"
|
BGP: Trigger IPv6 router advertisements upon config of unnumbered neighbor
Instead of turning on IPv6 RA on every interface as soon as it has an IPv6
address, only enable it upon configuration of BGP neighbor. When the BGP
neighbor is deleted, signal that RAs can be turned off.
To support this, introduce new message interaction between BGP and Zebra.
Also, take appropriate actions in BGP upon interface add/del since the
unnumbered neighbor could exist prior to interface creation etc.
Only unnumbered IPv6 neighbors require RA, the /30 or /31 based neighbors
don't. However, to keep the interaction simple and not have to deal with
too many dynamic conditions (e.g., address deletes or neighbor change to/from
'v6only'), RAs on the interface are triggered upon any unnumbered neighbor
configuration.
BGP-triggered RAs will cause RAs to be initiated on the interface; however,
if BGP asks that RAs be stopped (upon delete of unnumbered neighbor), RAs
will continue to be exchanged if the operator has explicitly enabled.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-10640
Reviewed By: CCR-4589
Testing Done: Various manual and automated (refer to defect)
2016-05-02 22:53:38 +02:00
|
|
|
#include "zebra/rtadv.h"
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Event list of zebra. */
|
|
|
|
enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE };
|
|
|
|
|
2004-05-09 11:09:59 +02:00
|
|
|
static void zebra_event (enum event event, int sock, struct zserv *client);
|
2003-03-01 12:42:20 +01:00
|
|
|
|
2003-06-04 15:59:38 +02:00
|
|
|
extern struct zebra_privs_t zserv_privs;
|
2014-06-04 06:53:35 +02: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 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
|
|
|
}
|
2015-05-20 02:47:22 +02:00
|
|
|
|
2016-07-28 17:23:39 +02:00
|
|
|
client->last_write_time = quagga_monotime();
|
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
|
|
|
|
2015-05-20 02:40:34 +02: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;
|
2015-05-20 02:47:22 +02:00
|
|
|
|
|
|
|
stream_set_getp(client->obuf, 0);
|
2016-06-03 10:56:10 +02:00
|
|
|
client->last_write_cmd = stream_getw_from(client->obuf, 6);
|
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;
|
|
|
|
}
|
2015-05-20 02:47:22 +02:00
|
|
|
|
2016-07-28 17:23:39 +02:00
|
|
|
client->last_write_time = quagga_monotime();
|
2003-03-01 12:42:20 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-20 02:40:34 +02:00
|
|
|
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)
|
2006-01-16 02:54:02 +01:00
|
|
|
{
|
|
|
|
/* 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);
|
2006-01-16 02:54:02 +01:00
|
|
|
stream_putw (s, cmd);
|
|
|
|
}
|
|
|
|
|
2012-03-22 01:13:39 +01:00
|
|
|
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);
|
2015-05-20 02:40:44 +02:00
|
|
|
stream_putc (s, ifp->ptm_enable);
|
|
|
|
stream_putc (s, ifp->ptm_status);
|
2012-03-22 01:13:39 +01:00
|
|
|
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
|
2012-09-26 14:52:39 +02:00
|
|
|
stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage));
|
2012-03-22 01:13:39 +01:00
|
|
|
#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));
|
|
|
|
}
|
|
|
|
|
2016-02-01 19:55:42 +01:00
|
|
|
static void
|
2016-03-22 21:37:17 +01:00
|
|
|
zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf)
|
2016-02-01 19:55:42 +01:00
|
|
|
{
|
|
|
|
/* Interface information. */
|
2016-03-22 21:37:17 +01:00
|
|
|
stream_put (s, zvrf->name, VRF_NAMSIZ);
|
2016-02-01 19:55:42 +01:00
|
|
|
|
|
|
|
/* 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. */
|
2004-05-09 11:09:59 +02:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
|
|
|
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);
|
2012-03-22 01:13:39 +01:00
|
|
|
zserv_encode_interface (s, ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 02:47:22 +02: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;
|
|
|
|
|
|
|
|
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);
|
2012-03-22 01:13:39 +01:00
|
|
|
zserv_encode_interface (s, ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 02:47:22 +02: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
|
|
|
}
|
|
|
|
|
2016-02-01 19:55:42 +01:00
|
|
|
int
|
2016-03-22 21:37:17 +01:00
|
|
|
zsend_vrf_add (struct zserv *client, struct zebra_vrf *zvrf)
|
2016-02-01 19:55:42 +01:00
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
|
|
|
|
s = client->obuf;
|
|
|
|
stream_reset (s);
|
|
|
|
|
2016-03-22 21:37:17 +01:00
|
|
|
zserv_create_header (s, ZEBRA_VRF_ADD, zvrf->vrf_id);
|
|
|
|
zserv_encode_vrf (s, zvrf);
|
2016-02-01 19:55:42 +01:00
|
|
|
|
|
|
|
client->vrfadd_cnt++;
|
|
|
|
return zebra_server_send_message(client);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* VRF deletion from zebra daemon. */
|
|
|
|
int
|
2016-03-22 21:37:17 +01:00
|
|
|
zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf)
|
2016-02-01 19:55:42 +01:00
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
|
|
|
|
s = client->obuf;
|
|
|
|
stream_reset (s);
|
|
|
|
|
2016-03-22 21:37:17 +01:00
|
|
|
zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf->vrf_id);
|
|
|
|
zserv_encode_vrf (s, zvrf);
|
2016-02-01 19:55:42 +01:00
|
|
|
|
|
|
|
client->vrfdel_cnt++;
|
|
|
|
return zebra_server_send_message (client);
|
|
|
|
}
|
|
|
|
|
2004-05-09 11:09:59 +02: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
|
|
|
|
* ^ ^ ^
|
2005-07-29 16:36:00 +02:00
|
|
|
* | | if_delete_update
|
|
|
|
* | |
|
2004-05-09 11:09:59 +02:00
|
|
|
* 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
|
2004-05-09 11:09:59 +02:00
|
|
|
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;
|
|
|
|
|
|
|
|
s = client->obuf;
|
|
|
|
stream_reset (s);
|
2006-01-16 02:54:02 +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
|
|
|
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);
|
2004-05-09 11:09:59 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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));
|
|
|
|
|
2015-05-20 02:47:22 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2015-05-20 02:40:40 +02: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;
|
|
|
|
|
|
|
|
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);
|
2015-05-20 02:40:40 +02:00
|
|
|
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))
|
2016-04-22 02:12:26 +02:00
|
|
|
zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, ifp, ifc);
|
2015-05-20 02:40:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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))
|
2016-04-22 02:12:26 +02:00
|
|
|
zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc);
|
2015-05-20 02:40:40 +02:00
|
|
|
}
|
|
|
|
|
2016-02-25 20:30:53 +01:00
|
|
|
/* Send addresses on interface to client */
|
|
|
|
int
|
|
|
|
zsend_interface_addresses (struct zserv *client, struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct listnode *cnode, *cnnode;
|
|
|
|
struct connected *c;
|
|
|
|
struct nbr_connected *nc;
|
|
|
|
|
|
|
|
/* Send interface addresses. */
|
|
|
|
for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
|
|
|
|
{
|
|
|
|
if (!CHECK_FLAG (c->conf, ZEBRA_IFC_REAL))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
|
|
|
|
ifp, c) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send interface neighbors. */
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Notify client about interface moving from one VRF to another.
|
|
|
|
* Whether client is interested in old and new VRF is checked by caller.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
zsend_interface_vrf_update (struct zserv *client, struct interface *ifp,
|
|
|
|
vrf_id_t vrf_id)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
|
|
|
|
s = client->obuf;
|
|
|
|
stream_reset (s);
|
|
|
|
|
|
|
|
zserv_create_header (s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
|
|
|
|
|
|
|
|
/* Fill in the ifIndex of the interface and its new VRF (id) */
|
|
|
|
stream_putl (s, ifp->ifindex);
|
|
|
|
stream_putw (s, vrf_id);
|
|
|
|
|
|
|
|
/* Write packet size. */
|
|
|
|
stream_putw_at (s, 0, stream_get_endp (s));
|
|
|
|
|
|
|
|
client->if_vrfchg_cnt++;
|
|
|
|
return zebra_server_send_message(client);
|
|
|
|
}
|
|
|
|
|
2016-05-13 07:57:40 +02:00
|
|
|
/* Add new nbr connected IPv6 address */
|
2015-05-20 02:40:40 +02:00
|
|
|
void
|
2016-05-13 07:57:40 +02:00
|
|
|
nbr_connected_add_ipv6 (struct interface *ifp, struct in6_addr *address)
|
2015-05-20 02:40:40 +02:00
|
|
|
{
|
|
|
|
struct nbr_connected *ifc;
|
|
|
|
struct prefix p;
|
|
|
|
|
|
|
|
p.family = AF_INET6;
|
|
|
|
IPV6_ADDR_COPY (&p.u.prefix, address);
|
2016-05-13 07:57:40 +02:00
|
|
|
p.prefixlen = IPV6_MAX_PREFIXLEN;
|
2015-05-20 02:40:40 +02:00
|
|
|
|
|
|
|
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);
|
2015-05-20 02:40:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-05-13 07:57:40 +02:00
|
|
|
nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address)
|
2015-05-20 02:40:40 +02:00
|
|
|
{
|
|
|
|
struct nbr_connected *ifc;
|
|
|
|
struct prefix p;
|
|
|
|
|
|
|
|
p.family = AF_INET6;
|
|
|
|
IPV6_ADDR_COPY (&p.u.prefix, address);
|
2016-05-13 07:57:40 +02:00
|
|
|
p.prefixlen = IPV6_MAX_PREFIXLEN;
|
2015-05-20 02:40:40 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2015-05-20 02:40:40 +02:00
|
|
|
nbr_connected_free (ifc);
|
|
|
|
}
|
|
|
|
|
2004-05-09 11:09:59 +02:00
|
|
|
/*
|
|
|
|
* 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
|
2004-05-09 11:09:59 +02:00
|
|
|
zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
|
|
|
|
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);
|
2012-03-22 01:13:39 +01:00
|
|
|
zserv_encode_interface (s, ifp);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 02:47:22 +02: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
|
|
|
}
|
|
|
|
|
2004-05-09 11:09:59 +02:00
|
|
|
/*
|
2015-10-21 06:38:38 +02: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.
|
2004-05-09 11:09:59 +02:00
|
|
|
*
|
2015-10-21 06:38:38 +02:00
|
|
|
* The primary difference is that this function merely sends a single NH instead of
|
|
|
|
* all the nexthops.
|
2004-05-09 11:09:59 +02:00
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
int
|
2015-10-21 06:38:38 +02:00
|
|
|
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;
|
2005-05-31 10:38:50 +02:00
|
|
|
unsigned long nhnummark = 0, messmark = 0;
|
2004-05-09 11:09:59 +02:00
|
|
|
int nhnum = 0;
|
2005-05-31 10:38:50 +02:00
|
|
|
u_char zapi_flags = 0;
|
2015-10-21 06:38:38 +02:00
|
|
|
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);
|
2015-10-21 06:38:38 +02:00
|
|
|
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);
|
|
|
|
|
2006-01-16 02:54:02 +01:00
|
|
|
/* 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);
|
2015-10-21 06:38:38 +02:00
|
|
|
|
2005-05-31 10:38:50 +02:00
|
|
|
/* 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);
|
2004-05-09 11:09:59 +02:00
|
|
|
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)
|
|
|
|
{
|
2015-10-21 06:38:38 +02:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2013-07-05 17:35:37 +02:00
|
|
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
|
|
|
|
|| nexthop_has_fib_child(nexthop))
|
2004-05-09 11:09:59 +02:00
|
|
|
{
|
2005-05-31 10:38:50 +02:00
|
|
|
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 */
|
|
|
|
}
|
2004-05-09 11:09:59 +02:00
|
|
|
nhnum++;
|
|
|
|
|
|
|
|
switch(nexthop->type)
|
|
|
|
{
|
|
|
|
case NEXTHOP_TYPE_IPV4:
|
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
|
|
stream_put_in_addr (s, &nexthop->gate.ipv4);
|
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
2015-10-21 06:38:38 +02:00
|
|
|
/* 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);
|
2004-05-09 11:09:59 +02:00
|
|
|
break;
|
|
|
|
default:
|
2015-10-21 06:38:38 +02:00
|
|
|
if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD
|
|
|
|
|| cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL)
|
2004-05-09 11:09:59 +02:00
|
|
|
{
|
|
|
|
struct in_addr empty;
|
2004-09-22 15:15:58 +02:00
|
|
|
memset (&empty, 0, sizeof (struct in_addr));
|
2004-05-09 11:09:59 +02:00
|
|
|
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 */
|
2015-10-21 06:38:38 +02:00
|
|
|
if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD || cmd == ZEBRA_REDISTRIBUTE_IPV6_ADD)
|
2005-05-31 10:38:50 +02:00
|
|
|
{
|
2005-09-29 13:25:50 +02:00
|
|
|
SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
|
|
|
|
stream_putc (s, rib->distance);
|
2005-05-31 10:38:50 +02:00
|
|
|
SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
|
|
|
|
stream_putl (s, rib->metric);
|
2015-05-20 02:46:33 +02:00
|
|
|
|
|
|
|
/* tag */
|
|
|
|
if (rib->tag)
|
|
|
|
{
|
|
|
|
SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
|
|
|
|
stream_putw(s, rib->tag);
|
|
|
|
}
|
2005-05-31 10:38:50 +02:00
|
|
|
}
|
2015-10-21 06:38:38 +02:00
|
|
|
|
2005-05-31 10:38:50 +02:00
|
|
|
/* write real message flags value */
|
|
|
|
stream_putc_at (s, messmark, zapi_flags);
|
2015-10-21 06:38:38 +02:00
|
|
|
|
2004-05-09 11:09:59 +02:00
|
|
|
/* Write next-hop number */
|
|
|
|
if (nhnummark)
|
2004-10-19 08:26:01 +02:00
|
|
|
stream_putc_at (s, nhnummark, nhnum);
|
2015-10-21 06:38:38 +02:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2004-05-09 11:09:59 +02: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);
|
2015-09-08 04:52:20 +02:00
|
|
|
stream_put (s, addr, 16);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (rib)
|
|
|
|
{
|
|
|
|
stream_putl (s, rib->metric);
|
|
|
|
num = 0;
|
2005-02-09 16:51:56 +01:00
|
|
|
nump = stream_get_endp(s);
|
2002-12-13 21:15:29 +01:00
|
|
|
stream_putc (s, 0);
|
2013-07-05 17:35:37 +02:00
|
|
|
/* 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:
|
|
|
|
stream_put (s, &nexthop->gate.ipv6, 16);
|
|
|
|
stream_putl (s, nexthop->ifindex);
|
|
|
|
break;
|
|
|
|
case ZEBRA_NEXTHOP_IFINDEX:
|
|
|
|
stream_putl (s, nexthop->ifindex);
|
|
|
|
break;
|
2004-03-04 18:45:00 +01:00
|
|
|
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));
|
2015-05-20 02:47:22 +02: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 zebra_server_send_message(client);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
#endif /* HAVE_IPV6 */
|
|
|
|
|
2004-05-09 11:09:59 +02: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_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. */
|
2015-01-22 19:09:36 +01:00
|
|
|
rib = rib_match_ipv4 (addr, SAFI_UNICAST, vrf_id, NULL);
|
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)
|
|
|
|
{
|
2013-05-25 16:01:35 +02:00
|
|
|
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;
|
2005-02-09 16:51:56 +01:00
|
|
|
nump = stream_get_endp(s);
|
2002-12-13 21:15:29 +01:00
|
|
|
stream_putc (s, 0);
|
2013-07-05 17:35:37 +02:00
|
|
|
/* 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;
|
2013-05-25 16:01:35 +02:00
|
|
|
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:
|
|
|
|
stream_putl (s, nexthop->ifindex);
|
|
|
|
break;
|
2004-03-04 18:45:00 +01:00
|
|
|
default:
|
|
|
|
/* do nothing */
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
stream_putc_at (s, nump, num);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-05-25 16:01:35 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2015-05-20 02:40:34 +02:00
|
|
|
/* Nexthop register */
|
|
|
|
static int
|
2015-05-20 03:04:20 +02:00
|
|
|
zserv_rnh_register (struct zserv *client, int sock, u_short length,
|
2016-04-20 22:12:29 +02:00
|
|
|
rnh_type_t type, struct zebra_vrf *zvrf)
|
2015-05-20 02:40:34 +02:00
|
|
|
{
|
|
|
|
struct rnh *rnh;
|
|
|
|
struct stream *s;
|
|
|
|
struct prefix p;
|
|
|
|
u_short l = 0;
|
2015-05-20 03:04:20 +02:00
|
|
|
u_char flags = 0;
|
2015-05-20 02:40:34 +02:00
|
|
|
|
|
|
|
if (IS_ZEBRA_DEBUG_NHT)
|
2015-05-20 03:04:20 +02:00
|
|
|
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");
|
2015-05-20 02:40:34 +02:00
|
|
|
|
|
|
|
s = client->ibuf;
|
|
|
|
|
2016-07-28 17:23:39 +02:00
|
|
|
client->nh_reg_time = quagga_monotime();
|
2015-05-20 03:04:20 +02:00
|
|
|
|
2015-05-20 02:40:34 +02:00
|
|
|
while (l < length)
|
|
|
|
{
|
2015-05-20 03:04:20 +02:00
|
|
|
flags = stream_getc(s);
|
2015-05-20 02:40:34 +02:00
|
|
|
p.family = stream_getw(s);
|
|
|
|
p.prefixlen = stream_getc(s);
|
2015-05-20 02:47:21 +02:00
|
|
|
l += 4;
|
2015-05-20 03:04:20 +02:00
|
|
|
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;
|
|
|
|
}
|
2016-04-20 22:12:29 +02:00
|
|
|
rnh = zebra_add_rnh(&p, zvrf->vrf_id, type);
|
2015-05-20 03:04:20 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-04-20 22:12:29 +02:00
|
|
|
zebra_add_rnh_client(rnh, client, type, zvrf->vrf_id);
|
2015-05-20 03:04:20 +02:00
|
|
|
/* Anything not AF_INET/INET6 has been filtered out above */
|
2016-04-20 22:12:29 +02:00
|
|
|
zebra_evaluate_rnh(zvrf->vrf_id, p.family, 1, type, &p);
|
2015-05-20 02:40:34 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Nexthop register */
|
|
|
|
static int
|
2015-05-20 03:04:20 +02:00
|
|
|
zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
|
2016-04-20 22:12:29 +02:00
|
|
|
rnh_type_t type, struct zebra_vrf *zvrf)
|
2015-05-20 02:40:34 +02:00
|
|
|
{
|
|
|
|
struct rnh *rnh;
|
|
|
|
struct stream *s;
|
|
|
|
struct prefix p;
|
|
|
|
u_short l = 0;
|
|
|
|
|
|
|
|
if (IS_ZEBRA_DEBUG_NHT)
|
2015-05-20 03:04:20 +02:00
|
|
|
zlog_debug("rnh_unregister msg from client %s: length=%d\n",
|
2015-05-20 02:40:34 +02:00
|
|
|
zebra_route_string(client->proto), length);
|
|
|
|
|
|
|
|
s = client->ibuf;
|
|
|
|
|
|
|
|
while (l < length)
|
|
|
|
{
|
2015-05-20 03:04:26 +02:00
|
|
|
(void)stream_getc(s); //Connected or not. Not used in this function
|
2015-05-20 02:40:34 +02:00
|
|
|
p.family = stream_getw(s);
|
|
|
|
p.prefixlen = stream_getc(s);
|
2015-05-20 02:47:21 +02:00
|
|
|
l += 4;
|
2015-05-20 03:04:20 +02:00
|
|
|
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;
|
|
|
|
}
|
2016-04-20 22:12:29 +02:00
|
|
|
rnh = zebra_lookup_rnh(&p, zvrf->vrf_id, type);
|
2015-05-20 02:40:34 +02:00
|
|
|
if (rnh)
|
2015-05-20 02:47:22 +02:00
|
|
|
{
|
2016-07-28 17:23:39 +02:00
|
|
|
client->nh_dereg_time = quagga_monotime();
|
2015-05-20 03:04:20 +02:00
|
|
|
zebra_remove_rnh_client(rnh, client, type);
|
2015-05-20 02:47:22 +02:00
|
|
|
}
|
2015-05-20 02:40:34 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-01 20:15:52 +02:00
|
|
|
/*
|
|
|
|
Modified version of zsend_ipv4_nexthop_lookup():
|
|
|
|
Query unicast rib if nexthop is not found on mrib.
|
|
|
|
Returns both route metric and protocol distance.
|
|
|
|
*/
|
|
|
|
static int
|
2015-01-06 19:53:24 +01:00
|
|
|
zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struct rib *rib, struct zebra_vrf *zvrf)
|
2014-07-01 20:15:52 +02:00
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
unsigned long nump;
|
|
|
|
u_char num;
|
|
|
|
struct nexthop *nexthop;
|
|
|
|
|
|
|
|
/* Get output stream. */
|
|
|
|
s = client->obuf;
|
|
|
|
stream_reset (s);
|
|
|
|
|
|
|
|
/* Fill in result. */
|
|
|
|
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf->vrf_id);
|
|
|
|
stream_put_in_addr (s, &addr);
|
|
|
|
|
|
|
|
if (rib)
|
|
|
|
{
|
|
|
|
stream_putc (s, rib->distance);
|
|
|
|
stream_putl (s, rib->metric);
|
|
|
|
num = 0;
|
|
|
|
nump = stream_get_endp(s); /* remember position for nexthop_num */
|
|
|
|
stream_putc (s, 0); /* reserve room for nexthop_num */
|
|
|
|
/* 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. */
|
|
|
|
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;
|
|
|
|
case ZEBRA_NEXTHOP_IFINDEX:
|
|
|
|
stream_putl (s, nexthop->ifindex);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* do nothing */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
num++;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream_putc_at (s, nump, num); /* store nexthop_num */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
stream_putc (s, 0); /* distance */
|
|
|
|
stream_putl (s, 0); /* metric */
|
|
|
|
stream_putc (s, 0); /* nexthop_num */
|
|
|
|
}
|
|
|
|
|
|
|
|
stream_putw_at (s, 0, stream_get_endp (s));
|
|
|
|
|
|
|
|
return zebra_server_send_message(client);
|
|
|
|
}
|
|
|
|
|
2004-05-09 11:09:59 +02: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_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;
|
2005-02-09 16:51:56 +01:00
|
|
|
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)
|
2013-07-05 17:35:37 +02:00
|
|
|
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;
|
2013-05-25 16:01:36 +02:00
|
|
|
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:
|
|
|
|
stream_putl (s, nexthop->ifindex);
|
|
|
|
break;
|
2004-03-04 18:45:00 +01:00
|
|
|
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));
|
2015-05-20 02:47:22 +02: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 zebra_server_send_message(client);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2004-10-03 20:18:34 +02:00
|
|
|
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
|
|
|
|
int
|
2015-05-22 11:40:07 +02:00
|
|
|
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
|
|
|
}
|
2014-06-04 06:53:35 +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
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *ifnode, *ifnnode;
|
2016-04-22 02:12:26 +02:00
|
|
|
vrf_iter_t iter;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct interface *ifp;
|
2016-04-22 02:12:26 +02:00
|
|
|
struct zebra_vrf *zvrf_iter;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Interface information is needed. */
|
2016-04-20 22:12:29 +02:00
|
|
|
vrf_bitmap_set (client->ifinfo, zvrf->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-04-22 02:12:26 +02:00
|
|
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-04-22 02:12:26 +02:00
|
|
|
zvrf_iter = vrf_iter2info (iter);
|
|
|
|
for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf_iter->vrf_id), ifnode, ifnnode, ifp))
|
|
|
|
{
|
|
|
|
/* Skip pseudo interface. */
|
|
|
|
if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
|
|
|
|
continue;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-04-22 02:12:26 +02:00
|
|
|
if (zsend_interface_add (client, ifp) < 0)
|
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-04-22 02:12:26 +02:00
|
|
|
if (zsend_interface_addresses (client, ifp) < 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
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-04-20 22:12:29 +02:00
|
|
|
vrf_bitmap_unset (client->ifinfo, zvrf->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
|
|
|
}
|
|
|
|
|
2015-09-16 14:30:23 +02:00
|
|
|
void
|
2016-06-08 21:30:48 +02:00
|
|
|
zserv_nexthop_num_warn (const char *caller, const struct prefix *p, const unsigned int nexthop_num)
|
2015-09-16 14:30:23 +02:00
|
|
|
{
|
2015-11-17 17:13:23 +01:00
|
|
|
if (nexthop_num > MULTIPATH_NUM)
|
2015-09-16 14:30:23 +02:00
|
|
|
{
|
2015-11-23 21:44:34 +01:00
|
|
|
char buff[PREFIX2STR_BUFFER];
|
|
|
|
prefix2str(p, buff, sizeof (buff));
|
2015-09-16 14:30:23 +02:00
|
|
|
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. */
|
2004-05-09 11:09:59 +02:00
|
|
|
/*
|
|
|
|
* 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
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
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;
|
2016-01-18 11:12:10 +01:00
|
|
|
ifindex_t ifindex;
|
2015-11-16 21:48:07 +01:00
|
|
|
safi_t safi;
|
2015-05-20 02:47:22 +02:00
|
|
|
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);
|
2004-05-09 11:09:59 +02:00
|
|
|
message = stream_getc (s);
|
2011-11-26 18:59:32 +01:00
|
|
|
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));
|
|
|
|
|
2015-05-22 11:40:02 +02:00
|
|
|
/* VRF ID */
|
2016-04-20 22:12:29 +02:00
|
|
|
rib->vrf_id = zvrf->vrf_id;
|
2015-05-22 11:40:02 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Nexthop parse. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
|
|
|
|
{
|
|
|
|
nexthop_num = stream_getc (s);
|
2015-09-16 14:30:23 +02:00
|
|
|
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);
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_ifindex_add (rib, ifindex);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_NEXTHOP_IPV4:
|
|
|
|
nexthop.s_addr = stream_get_ipv4 (s);
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_ipv4_add (rib, &nexthop, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2012-07-07 17:06:13 +02:00
|
|
|
case ZEBRA_NEXTHOP_IPV4_IFINDEX:
|
|
|
|
nexthop.s_addr = stream_get_ipv4 (s);
|
|
|
|
ifindex = stream_getl (s);
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex);
|
2012-07-07 17:06:13 +02:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case ZEBRA_NEXTHOP_IPV6:
|
2005-02-09 16:51:56 +01:00
|
|
|
stream_forward_getp (s, IPV6_MAX_BYTELEN);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2012-03-28 04:21:29 +02:00
|
|
|
case ZEBRA_NEXTHOP_BLACKHOLE:
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_blackhole_add (rib);
|
2012-03-28 04:21:29 +02:00
|
|
|
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);
|
|
|
|
|
2015-05-20 02:46:33 +02:00
|
|
|
/* Tag */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
|
|
|
|
rib->tag = stream_getw (s);
|
|
|
|
else
|
|
|
|
rib->tag = 0;
|
|
|
|
|
2006-07-27 18:11:02 +02:00
|
|
|
/* Table */
|
2016-04-20 22:12:29 +02:00
|
|
|
rib->table = zvrf->table_id;
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2015-05-20 02:47:22 +02:00
|
|
|
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
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct stream *s;
|
|
|
|
struct zapi_ipv4 api;
|
2012-03-28 04:21:29 +02:00
|
|
|
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;
|
2016-02-01 19:55:42 +01:00
|
|
|
u_int32_t table_id;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
s = client->ibuf;
|
|
|
|
ifindex = 0;
|
|
|
|
nexthop.s_addr = 0;
|
2012-03-28 04:21:29 +02:00
|
|
|
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);
|
2011-11-26 18:59:32 +01:00
|
|
|
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_IPV4:
|
|
|
|
nexthop.s_addr = stream_get_ipv4 (s);
|
2012-03-28 04:21:29 +02:00
|
|
|
nexthop_p = &nexthop;
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2012-07-07 17:06:13 +02:00
|
|
|
case ZEBRA_NEXTHOP_IPV4_IFINDEX:
|
|
|
|
nexthop.s_addr = stream_get_ipv4 (s);
|
2013-11-27 18:06:14 +01:00
|
|
|
nexthop_p = &nexthop;
|
2012-07-07 17:06:13 +02:00
|
|
|
ifindex = stream_getl (s);
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case ZEBRA_NEXTHOP_IPV6:
|
2005-02-09 16:51:56 +01:00
|
|
|
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;
|
|
|
|
|
2015-05-20 02:46:33 +02:00
|
|
|
/* tag */
|
|
|
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
|
|
|
|
api.tag = stream_getw (s);
|
|
|
|
else
|
|
|
|
api.tag = 0;
|
|
|
|
|
2016-04-20 22:12:29 +02:00
|
|
|
table_id = zvrf->table_id;
|
2016-02-01 19:55:42 +01:00
|
|
|
|
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,
|
2016-04-20 22:12:29 +02:00
|
|
|
zvrf->vrf_id, table_id, api.safi);
|
2015-05-20 02:47:22 +02:00
|
|
|
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,
|
2016-04-20 22:12:29 +02:00
|
|
|
struct zebra_vrf *zvrf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in_addr addr;
|
2013-05-25 16:01:35 +02:00
|
|
|
char buf[BUFSIZ];
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
addr.s_addr = stream_get_ipv4 (client->ibuf);
|
2013-05-25 16:01:35 +02:00
|
|
|
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
|
|
|
|
zlog_debug("%s: looking up %s", __func__,
|
|
|
|
inet_ntop (AF_INET, &addr, buf, BUFSIZ));
|
2016-04-20 22:12:29 +02:00
|
|
|
return zsend_ipv4_nexthop_lookup (client, addr, zvrf->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2014-07-01 20:15:52 +02:00
|
|
|
/* MRIB Nexthop lookup for IPv4. */
|
|
|
|
static int
|
|
|
|
zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
|
|
|
{
|
|
|
|
struct in_addr addr;
|
2015-01-06 19:53:24 +01:00
|
|
|
struct rib *rib;
|
2014-07-01 20:15:52 +02:00
|
|
|
|
|
|
|
addr.s_addr = stream_get_ipv4 (client->ibuf);
|
2015-01-06 19:53:24 +01:00
|
|
|
rib = rib_match_ipv4_multicast (addr, NULL);
|
|
|
|
return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib, zvrf);
|
2014-07-01 20:15:52 +02:00
|
|
|
}
|
|
|
|
|
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,
|
2016-04-20 22:12:29 +02:00
|
|
|
struct zebra_vrf *zvrf)
|
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);
|
|
|
|
|
2016-04-20 22:12:29 +02:00
|
|
|
return zsend_ipv4_import_lookup (client, &p, zvrf->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2015-06-11 18:19:12 +02:00
|
|
|
/* Zebra server IPv6 prefix add function. */
|
|
|
|
static int
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
2015-06-11 18:19:12 +02:00
|
|
|
{
|
|
|
|
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));
|
|
|
|
|
2016-04-06 23:07:05 +02:00
|
|
|
/* VRF ID */
|
2016-04-20 22:12:29 +02:00
|
|
|
rib->vrf_id = zvrf->vrf_id;
|
2016-04-06 23:07:05 +02:00
|
|
|
|
2015-06-11 18:19:12 +02:00
|
|
|
/* 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);
|
2015-09-16 14:30:23 +02:00
|
|
|
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num);
|
2015-06-11 18:19:12 +02:00
|
|
|
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:
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_blackhole_add (rib);
|
2015-06-11 18:19:12 +02:00
|
|
|
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]) {
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
|
2015-06-11 18:19:12 +02:00
|
|
|
}
|
|
|
|
else {
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_ipv6_add (rib, &nexthops[i]);
|
2015-06-11 18:19:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ((i < if_count) && ifindices[i]) {
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_ifindex_add (rib, ifindices[i]);
|
2015-06-11 18:19:12 +02: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 */
|
2016-04-20 22:12:29 +02:00
|
|
|
rib->table = zvrf->table_id;
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2015-06-11 18:19:12 +02:00
|
|
|
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
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct stream *s;
|
|
|
|
struct in6_addr nexthop;
|
2015-05-20 02:24:43 +02:00
|
|
|
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;
|
2015-05-20 02:24:43 +02:00
|
|
|
safi_t safi;
|
|
|
|
static struct in6_addr nexthops[MULTIPATH_NUM];
|
|
|
|
static unsigned int ifindices[MULTIPATH_NUM];
|
2015-05-20 02:47:22 +02:00
|
|
|
int ret;
|
2015-05-20 02:24:43 +02:00
|
|
|
|
|
|
|
/* Get input stream. */
|
2002-12-13 21:15:29 +01:00
|
|
|
s = client->ibuf;
|
2015-05-20 02:24:43 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
ifindex = 0;
|
|
|
|
memset (&nexthop, 0, sizeof (struct in6_addr));
|
|
|
|
|
2015-05-20 02:24:43 +02:00
|
|
|
/* Allocate new rib. */
|
|
|
|
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Type, flags, message. */
|
2015-05-20 02:24:43 +02:00
|
|
|
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);
|
2015-05-20 02:24:43 +02:00
|
|
|
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
|
|
|
|
2015-05-20 02:24:43 +02: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));
|
|
|
|
|
2015-05-20 02:24:43 +02:00
|
|
|
/* 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
|
|
|
{
|
2015-05-20 02:24:43 +02:00
|
|
|
int nh_count = 0;
|
|
|
|
int if_count = 0;
|
|
|
|
int max_nh_if = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 02:24:43 +02:00
|
|
|
nexthop_num = stream_getc (s);
|
2015-09-16 14:30:23 +02:00
|
|
|
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);
|
2015-05-20 02:24:43 +02:00
|
|
|
if (nh_count < MULTIPATH_NUM) {
|
|
|
|
nexthops[nh_count++] = nexthop;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_NEXTHOP_IFINDEX:
|
2015-05-20 02:24:43 +02:00
|
|
|
if (if_count < MULTIPATH_NUM) {
|
|
|
|
ifindices[if_count++] = stream_getl (s);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2015-05-20 03:03:39 +02:00
|
|
|
case ZEBRA_NEXTHOP_BLACKHOLE:
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_blackhole_add (rib);
|
2015-05-20 03:03:39 +02:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
2015-05-20 02:24:43 +02: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])) {
|
2015-11-10 02:02:26 +01:00
|
|
|
if ((i < if_count) && ifindices[i])
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]);
|
2015-11-10 02:02:26 +01:00
|
|
|
else
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_ipv6_add (rib, &nexthops[i]);
|
2015-05-20 02:24:43 +02:00
|
|
|
}
|
|
|
|
else {
|
2015-11-10 02:02:26 +01:00
|
|
|
if ((i < if_count) && ifindices[i])
|
2015-11-27 17:46:54 +01:00
|
|
|
rib_nexthop_ifindex_add (rib, ifindices[i]);
|
2015-05-20 02:24:43 +02:00
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2015-05-20 02:24:43 +02:00
|
|
|
/* Distance. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
|
|
|
|
rib->distance = stream_getc (s);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 02:24:43 +02:00
|
|
|
/* Metric. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
|
|
|
|
rib->metric = stream_getl (s);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-20 02:46:33 +02:00
|
|
|
/* Tag */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
|
|
|
|
rib->tag = stream_getw (s);
|
|
|
|
else
|
|
|
|
rib->tag = 0;
|
|
|
|
|
2016-04-06 23:07:05 +02:00
|
|
|
/* VRF ID */
|
2016-04-20 22:12:29 +02:00
|
|
|
rib->vrf_id = zvrf->vrf_id;
|
|
|
|
rib->table = zvrf->table_id;
|
2016-04-06 23:07:05 +02:00
|
|
|
|
2015-06-11 18:19:12 +02:00
|
|
|
ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
|
2015-05-20 02:47:22 +02:00
|
|
|
/* 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
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
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);
|
2011-11-26 19:10:39 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-20 02:46:33 +02:00
|
|
|
/* 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;
|
2015-05-20 02:46:33 +02:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
2015-05-20 02:46:33 +02:00
|
|
|
/* 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))
|
2015-05-22 11:40:02 +02:00
|
|
|
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, NULL, ifindex,
|
2016-04-20 22:12:29 +02:00
|
|
|
zvrf->vrf_id, client->rtm_table, api.safi);
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2015-05-22 11:40:02 +02:00
|
|
|
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, &nexthop, ifindex,
|
2016-04-20 22:12:29 +02:00
|
|
|
zvrf->vrf_id, client->rtm_table, api.safi);
|
2015-05-20 02:47:22 +02:00
|
|
|
|
|
|
|
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,
|
2016-04-20 22:12:29 +02:00
|
|
|
struct zebra_vrf *zvrf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in6_addr addr;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
stream_get (&addr, client->ibuf, 16);
|
2013-04-11 10:24:29 +02:00
|
|
|
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
|
|
|
|
2016-04-20 22:12:29 +02:00
|
|
|
return zsend_ipv6_nexthop_lookup (client, &addr, zvrf->vrf_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
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
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_router_id_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
2004-10-03 20:18:34 +02:00
|
|
|
{
|
|
|
|
struct prefix p;
|
|
|
|
|
|
|
|
/* Router-id information is needed. */
|
2016-04-20 22:12:29 +02:00
|
|
|
vrf_bitmap_set (client->ridinfo, zvrf->vrf_id);
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2016-04-20 22:12:29 +02:00
|
|
|
router_id_get (&p, zvrf->vrf_id);
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2016-04-20 22:12:29 +02:00
|
|
|
return zsend_router_id_update (client, &p, zvrf->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
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_router_id_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
2004-10-03 20:18:34 +02:00
|
|
|
{
|
2016-04-20 22:12:29 +02:00
|
|
|
vrf_bitmap_unset (client->ridinfo, zvrf->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
|
|
|
}
|
|
|
|
|
2011-12-11 15:48:47 +01: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;
|
|
|
|
|
2011-12-11 15:48:47 +01:00
|
|
|
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);
|
2011-12-11 15:48:47 +01:00
|
|
|
|
|
|
|
/* 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);
|
2011-12-11 15:48:47 +01:00
|
|
|
|
2015-05-20 02:40:34 +02:00
|
|
|
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;
|
2011-12-11 15:48:47 +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
|
|
|
/* Unregister all information in a VRF. */
|
|
|
|
static int
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_vrf_unregister (struct zserv *client, u_short length, struct zebra_vrf *zvrf)
|
*: 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;
|
|
|
|
|
|
|
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
|
|
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
2016-04-20 22:12:29 +02:00
|
|
|
vrf_bitmap_unset (client->redist[afi][i], zvrf->vrf_id);
|
|
|
|
vrf_bitmap_unset (client->redist_default, zvrf->vrf_id);
|
|
|
|
vrf_bitmap_unset (client->ifinfo, zvrf->vrf_id);
|
|
|
|
vrf_bitmap_unset (client->ridinfo, zvrf->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
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-03-02 02:08:43 +01:00
|
|
|
/* Cleanup registered nexthops (across VRFs) upon client disconnect. */
|
|
|
|
static void
|
|
|
|
zebra_client_close_cleanup_rnh (struct zserv *client)
|
|
|
|
{
|
|
|
|
vrf_iter_t iter;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
|
|
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
|
|
|
{
|
|
|
|
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
|
|
|
{
|
|
|
|
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_NEXTHOP_TYPE);
|
|
|
|
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_NEXTHOP_TYPE);
|
|
|
|
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET, client, RNH_IMPORT_CHECK_TYPE);
|
|
|
|
zebra_cleanup_rnh_client(zvrf->vrf_id, AF_INET6, client, RNH_IMPORT_CHECK_TYPE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Close zebra client. */
|
2004-05-09 11:09:59 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
zebra_client_close (struct zserv *client)
|
|
|
|
{
|
2016-05-09 05:11:18 +02:00
|
|
|
/* Send client de-registration to BFD */
|
2016-06-21 12:39:58 +02:00
|
|
|
zebra_ptm_bfd_client_deregister(client->proto);
|
2016-05-09 05:11:18 +02:00
|
|
|
|
2016-03-02 02:08:43 +01:00
|
|
|
/* Cleanup any registered nexthops - across all VRFs. */
|
|
|
|
zebra_client_close_cleanup_rnh (client);
|
2015-05-20 02:40:34 +02:00
|
|
|
|
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. */
|
2003-06-15 03:28:29 +02:00
|
|
|
listnode_delete (zebrad.client_list, client);
|
2016-07-28 17:23:49 +02:00
|
|
|
XFREE (MTYPE_TMP, client);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Make new client. */
|
2004-05-09 11:09:59 +02:00
|
|
|
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
|
|
|
|
2016-07-28 17:23:49 +02:00
|
|
|
client = XCALLOC (MTYPE_TMP, sizeof (struct zserv));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* 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. */
|
2003-06-15 03:28:29 +02:00
|
|
|
client->rtm_table = zebrad.rtm_table_default;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-07-28 17:23:39 +02:00
|
|
|
client->connect_time = quagga_monotime();
|
*: 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 ();
|
2015-05-20 02:47:22 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Add this client to linked list. */
|
2003-06-15 03:28:29 +02:00
|
|
|
listnode_add (zebrad.client_list, client);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Make new read thread. */
|
|
|
|
zebra_event (ZEBRA_READ, sock, client);
|
2016-02-01 19:55:42 +01:00
|
|
|
|
|
|
|
zebra_vrf_update_all (client);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Handler of zebra service request. */
|
2004-05-09 11:09:59 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
zebra_client_read (struct thread *thread)
|
|
|
|
{
|
|
|
|
int sock;
|
|
|
|
struct zserv *client;
|
2005-04-10 17:01:56 +02:00
|
|
|
size_t already;
|
2006-01-16 02:54:02 +01:00
|
|
|
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;
|
2016-04-20 22:12:29 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
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). */
|
2005-04-10 17:01:56 +02:00
|
|
|
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
|
|
|
{
|
2005-04-10 17:01:56 +02: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,
|
2005-04-10 17:01:56 +02:00
|
|
|
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;
|
|
|
|
}
|
2005-04-10 17:01:56 +02:00
|
|
|
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;
|
|
|
|
}
|
2005-04-10 17:01:56 +02:00
|
|
|
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);
|
|
|
|
|
2006-01-16 02:54:02 +01:00
|
|
|
/* Fetch header values */
|
2002-12-13 21:15:29 +01:00
|
|
|
length = stream_getw (client->ibuf);
|
2006-01-16 02:54:02 +01:00
|
|
|
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);
|
2006-01-16 02:54:02 +01:00
|
|
|
command = stream_getw (client->ibuf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2006-01-16 02:54:02 +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
|
|
|
{
|
2005-04-10 17:01:56 +02: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. */
|
2005-04-10 17:01:56 +02:00
|
|
|
if (already < length)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-04-10 17:01:56 +02: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)
|
2004-12-07 22:12:56 +01:00
|
|
|
zlog_debug ("connection closed [%d] when reading zebra data", sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
zebra_client_close (client);
|
|
|
|
return -1;
|
|
|
|
}
|
2005-04-10 17:01:56 +02:00
|
|
|
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)
|
2004-12-07 22:12:56 +01:00
|
|
|
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
|
|
|
|
2016-07-28 17:23:39 +02:00
|
|
|
client->last_read_time = quagga_monotime();
|
2015-05-20 02:47:22 +02:00
|
|
|
client->last_read_cmd = command;
|
|
|
|
|
2016-04-20 22:12:29 +02:00
|
|
|
zvrf = zebra_vrf_lookup (vrf_id);
|
|
|
|
if (!zvrf)
|
|
|
|
{
|
|
|
|
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
|
|
|
|
zlog_debug ("zebra received unknown VRF[%u]", vrf_id);
|
|
|
|
goto zclient_read_out;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (command)
|
|
|
|
{
|
2004-10-03 20:18:34 +02:00
|
|
|
case ZEBRA_ROUTER_ID_ADD:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_router_id_add (client, length, zvrf);
|
2004-10-03 20:18:34 +02:00
|
|
|
break;
|
|
|
|
case ZEBRA_ROUTER_ID_DELETE:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_router_id_delete (client, length, zvrf);
|
2004-10-03 20:18:34 +02:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case ZEBRA_INTERFACE_ADD:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_interface_add (client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_INTERFACE_DELETE:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_interface_delete (client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_IPV4_ROUTE_ADD:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv4_add (client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_IPV4_ROUTE_DELETE:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv4_delete (client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2015-06-11 18:19:12 +02:00
|
|
|
case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv4_route_ipv6_nexthop_add (client, length, zvrf);
|
2015-06-11 18:19:12 +02:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case ZEBRA_IPV6_ROUTE_ADD:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv6_add (client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_IPV6_ROUTE_DELETE:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv6_delete (client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_REDISTRIBUTE_ADD:
|
2016-04-20 22:12:29 +02:00
|
|
|
zebra_redistribute_add (command, client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_REDISTRIBUTE_DELETE:
|
2016-04-20 22:12:29 +02:00
|
|
|
zebra_redistribute_delete (command, client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_REDISTRIBUTE_DEFAULT_ADD:
|
2016-04-20 22:12:29 +02:00
|
|
|
zebra_redistribute_default_add (command, client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE:
|
2016-04-20 22:12:29 +02:00
|
|
|
zebra_redistribute_default_delete (command, client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_IPV4_NEXTHOP_LOOKUP:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv4_nexthop_lookup (client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2014-07-01 20:15:52 +02:00
|
|
|
case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
|
|
|
|
zread_ipv4_nexthop_lookup_mrib (client, length, zvrf);
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case ZEBRA_IPV6_NEXTHOP_LOOKUP:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv6_nexthop_lookup (client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_IPV4_IMPORT_LOOKUP:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_ipv4_import_lookup (client, length, zvrf);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2011-12-11 15:48:47 +01:00
|
|
|
case ZEBRA_HELLO:
|
|
|
|
zread_hello (client);
|
|
|
|
break;
|
2015-05-20 02:40:34 +02:00
|
|
|
case ZEBRA_NEXTHOP_REGISTER:
|
2016-04-20 22:12:29 +02:00
|
|
|
zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE, zvrf);
|
2015-05-20 02:40:34 +02:00
|
|
|
break;
|
|
|
|
case ZEBRA_NEXTHOP_UNREGISTER:
|
2016-04-20 22:12:29 +02:00
|
|
|
zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE, zvrf);
|
2015-05-20 03:04:20 +02:00
|
|
|
break;
|
|
|
|
case ZEBRA_IMPORT_ROUTE_REGISTER:
|
2016-04-20 22:12:29 +02:00
|
|
|
zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE, zvrf);
|
2015-05-20 03:04:20 +02:00
|
|
|
break;
|
|
|
|
case ZEBRA_IMPORT_ROUTE_UNREGISTER:
|
2016-04-20 22:12:29 +02:00
|
|
|
zserv_rnh_unregister(client, sock, length, RNH_IMPORT_CHECK_TYPE, zvrf);
|
2015-05-20 02:40:34 +02:00
|
|
|
break;
|
2015-06-12 16:59:11 +02:00
|
|
|
case ZEBRA_BFD_DEST_UPDATE:
|
|
|
|
case ZEBRA_BFD_DEST_REGISTER:
|
2016-04-20 22:12:29 +02:00
|
|
|
zebra_ptm_bfd_dst_register(client, sock, length, command, zvrf);
|
2015-06-12 16:59:11 +02:00
|
|
|
break;
|
|
|
|
case ZEBRA_BFD_DEST_DEREGISTER:
|
2016-04-20 22:12:29 +02:00
|
|
|
zebra_ptm_bfd_dst_deregister(client, sock, length, zvrf);
|
2015-06-12 16:59:11 +02:00
|
|
|
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:
|
2016-04-20 22:12:29 +02:00
|
|
|
zread_vrf_unregister (client, length, zvrf);
|
*: 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
|
|
|
break;
|
Support for multi-client and client reg msg
Ticket: CM-7615, CM-7773
Reviewed By: CCR-3610, CCR-3708
Testing Done: Unit, BGP Smoke and OSPF Smoke
Changes (70790261926b17200c8c9377c4576cd3b486fcef) ported from 2.5
Issue (related to CM-7615): 1. CM-7615: There is mismatch in the client name between ptm display of client BFD sessions and the zebra logs. For example, if bgpd added BFD session, zebra logs will show the client as “bgp” but the ptm display will show it as “quagga”
2. Bigger problem is when 2 clients (for example OSPF and BGP) from Quagga register for same BFD session and only one client de-registers the BFD session. This results in BFD session deletion from PTM even though other client still has the BFD registration.
Root Cause: Even though BGP, OSPF and OSPF6 are 3 different clients from Quagga that are trying to register/deregister BFD sessions with PTM, all 3 are represented as one client “quagga” from zebra. This makes it hard for PTM/BFD to distinguish between all three when BFD peer registration/deregistration happens from the clients.
Fix: Send the actual client name bgp, ospf or ospf6 from zebra with BFD reg/dereg messages instead of one unified client name “quagga”
CM-7773: BFD sessions are not getting cleaned from PTM even though no BGP peering exists in Quagga.
Root Cause: PTM cleans up stale BFD sessions from a client when it finds a change in seq id advertised by the client. But, if PTM never detects a change in the seq id then the stale BFD sessions never get cleaned up. The test restarts the quagga without saving the configuration, which results in no BGP peering. No BGP peers are registered with PTM after restart and PTM does not detect a client seq id change resulting in stale BFD sessions.
Fix: New client registration message was added in PTM. Every client that is interested in BFD monitoring will register with PTM with the client seq id. Client will register with a different seq id (typically pid) every time it restarts. This will help in detecting the change in seq id and cleanup of stale BFD sessions for a client.
Code Changes: To support the new client registration message following changes have been made
- Added support for client registration messaging in zebra for sending messages to PTM.
- Added support for client registration messaging between zebra and clients (BGP, OSPF and OSPF6) in BFD library.
- Expanded the reg/de reg peer messaging between zebra and clients to support client specific seq id to distinguish between multiple clients registering for BFD peer rather than one “quagga” client.
- Changes in bgpd, ospfd and ospf6d to send client registrations at the time of daemon initialization and on receiving BFD peer replay message.
2016-03-09 08:31:32 +01:00
|
|
|
case ZEBRA_BFD_CLIENT_REGISTER:
|
|
|
|
zebra_ptm_bfd_client_register(client, sock, length);
|
|
|
|
break;
|
BGP: Trigger IPv6 router advertisements upon config of unnumbered neighbor
Instead of turning on IPv6 RA on every interface as soon as it has an IPv6
address, only enable it upon configuration of BGP neighbor. When the BGP
neighbor is deleted, signal that RAs can be turned off.
To support this, introduce new message interaction between BGP and Zebra.
Also, take appropriate actions in BGP upon interface add/del since the
unnumbered neighbor could exist prior to interface creation etc.
Only unnumbered IPv6 neighbors require RA, the /30 or /31 based neighbors
don't. However, to keep the interaction simple and not have to deal with
too many dynamic conditions (e.g., address deletes or neighbor change to/from
'v6only'), RAs on the interface are triggered upon any unnumbered neighbor
configuration.
BGP-triggered RAs will cause RAs to be initiated on the interface; however,
if BGP asks that RAs be stopped (upon delete of unnumbered neighbor), RAs
will continue to be exchanged if the operator has explicitly enabled.
Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-10640
Reviewed By: CCR-4589
Testing Done: Various manual and automated (refer to defect)
2016-05-02 22:53:38 +02:00
|
|
|
case ZEBRA_INTERFACE_ENABLE_RADV:
|
|
|
|
zebra_interface_radv_set (client, sock, length, zvrf, 1);
|
|
|
|
break;
|
|
|
|
case ZEBRA_INTERFACE_DISABLE_RADV:
|
|
|
|
zebra_interface_radv_set (client, sock, length, zvrf, 0);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-04-20 22:12:29 +02:00
|
|
|
zclient_read_out:
|
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. */
|
2004-05-09 11:09:59 +02:00
|
|
|
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)
|
|
|
|
{
|
2004-11-20 03:06:59 +01:00
|
|
|
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);
|
2005-01-05 09:30:35 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new zebra client. */
|
|
|
|
zebra_client_create (client_sock);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-05-09 11:09:59 +02:00
|
|
|
#ifdef HAVE_TCP_ZEBRA
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Make zebra's server socket. */
|
2004-05-09 11:09:59 +02:00
|
|
|
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)
|
|
|
|
{
|
2005-04-05 02:45:23 +02:00
|
|
|
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);
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
2002-12-13 21:15:29 +01:00
|
|
|
addr.sin_len = sizeof (struct sockaddr_in);
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#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);
|
|
|
|
|
2003-06-04 15:59:38 +02:00
|
|
|
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)
|
|
|
|
{
|
2005-04-05 02:45:23 +02:00
|
|
|
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;
|
|
|
|
}
|
2003-06-04 15:59:38 +02:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2005-04-05 02:45:23 +02:00
|
|
|
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);
|
|
|
|
}
|
2015-04-21 09:47:57 +02:00
|
|
|
#else /* HAVE_TCP_ZEBRA */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* For sockaddr_un. */
|
|
|
|
#include <sys/un.h>
|
|
|
|
|
|
|
|
/* zebra server UNIX domain socket. */
|
2004-05-09 11:09:59 +02:00
|
|
|
static void
|
2004-10-07 22:29:24 +02:00
|
|
|
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)
|
|
|
|
{
|
2005-04-05 02:45:23 +02:00
|
|
|
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));
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#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);
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#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)
|
|
|
|
{
|
2005-04-05 02:45:23 +02:00
|
|
|
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)
|
|
|
|
{
|
2005-04-05 02:45:23 +02:00
|
|
|
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);
|
|
|
|
}
|
2015-04-21 09:47:57 +02:00
|
|
|
#endif /* HAVE_TCP_ZEBRA */
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2004-05-09 11:09:59 +02: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:
|
2003-06-15 03:28:29 +02:00
|
|
|
thread_add_read (zebrad.master, zebra_accept, client, sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_READ:
|
|
|
|
client->t_read =
|
2003-06-15 03:28:29 +02:00
|
|
|
thread_add_read (zebrad.master, zebra_client_read, client, sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_WRITE:
|
|
|
|
/**/
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2015-05-20 02:47:22 +02:00
|
|
|
#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);
|
|
|
|
}
|
|
|
|
|
2016-07-28 17:23:39 +02:00
|
|
|
now = quagga_monotime();
|
2015-05-20 02:47:22 +02:00
|
|
|
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);
|
|
|
|
|
2015-05-20 02:47:22 +02:00
|
|
|
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);
|
2015-06-12 16:59:11 +02:00
|
|
|
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);
|
2015-05-20 02:47:22 +02:00
|
|
|
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")
|
|
|
|
{
|
2003-06-15 03:28:29 +02:00
|
|
|
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")
|
|
|
|
{
|
2003-06-15 03:28:29 +02:00
|
|
|
zebrad.rtm_table_default = strtol (argv[0], (char**)0, 10);
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-11-23 19:05:03 +01:00
|
|
|
DEFUN (no_config_table,
|
|
|
|
no_config_table_cmd,
|
|
|
|
"no table TABLENO",
|
|
|
|
NO_STR
|
|
|
|
"Configure target kernel routing table\n"
|
|
|
|
"TABLE integer\n")
|
|
|
|
{
|
|
|
|
zebrad.rtm_table_default = 0;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-05-25 13:43:52 +02:00
|
|
|
DEFUN (ip_forwarding,
|
|
|
|
ip_forwarding_cmd,
|
|
|
|
"ip forwarding",
|
|
|
|
IP_STR
|
|
|
|
"Turn on IP forwarding")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ipforward ();
|
2004-10-13 14:20:35 +02:00
|
|
|
if (ret == 0)
|
|
|
|
ret = ipforward_on ();
|
2003-05-25 13:43:52 +02:00
|
|
|
|
|
|
|
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 ();
|
2004-10-13 14:20:35 +02:00
|
|
|
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")
|
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct zserv *client;
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
2015-05-20 02:47:22 +02:00
|
|
|
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);
|
2015-05-20 02:40:34 +02:00
|
|
|
|
2015-05-20 02:47:22 +02:00
|
|
|
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. */
|
2004-05-09 11:09:59 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
config_write_table (struct vty *vty)
|
|
|
|
{
|
2003-06-15 03:28:29 +02:00
|
|
|
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. */
|
2008-12-01 20:10:34 +01:00
|
|
|
static struct cmd_node table_node =
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
TABLE_NODE,
|
|
|
|
"", /* This node has no interface. */
|
|
|
|
1
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2004-02-11 23:42:16 +01:00
|
|
|
DEFUN (ipv6_forwarding,
|
|
|
|
ipv6_forwarding_cmd,
|
|
|
|
"ipv6 forwarding",
|
|
|
|
IPV6_STR
|
|
|
|
"Turn on IPv6 forwarding")
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2004-04-06 13:59:00 +02:00
|
|
|
ret = ipforward_ipv6 ();
|
2004-10-13 14:20:35 +02:00
|
|
|
if (ret == 0)
|
|
|
|
ret = ipforward_ipv6_on ();
|
2004-04-06 13:59:00 +02:00
|
|
|
|
|
|
|
if (ret == 0)
|
2004-02-11 23:42:16 +01:00
|
|
|
{
|
|
|
|
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
|
2004-02-11 23:42:16 +01:00
|
|
|
IPV6_STR
|
|
|
|
"Turn off IPv6 forwarding")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2004-04-06 13:59:00 +02:00
|
|
|
ret = ipforward_ipv6 ();
|
2004-10-13 14:20:35 +02:00
|
|
|
if (ret != 0)
|
|
|
|
ret = ipforward_ipv6_off ();
|
2004-04-06 13:59:00 +02:00
|
|
|
|
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);
|
|
|
|
|
2016-06-21 21:57:22 +02:00
|
|
|
if (!ipforward ())
|
|
|
|
vty_out (vty, "no ip forwarding%s", VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
#ifdef HAVE_IPV6
|
2016-06-21 21:57:22 +02:00
|
|
|
if (!ipforward_ipv6 ())
|
|
|
|
vty_out (vty, "no 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. */
|
2008-12-01 20:10:34 +01:00
|
|
|
static struct cmd_node forwarding_node =
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
FORWARDING_NODE,
|
|
|
|
"", /* This node has no interface. */
|
|
|
|
1
|
|
|
|
};
|
|
|
|
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Initialisation of zebra and installation of commands. */
|
|
|
|
void
|
2005-06-28 19:17:12 +02:00
|
|
|
zebra_init (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
/* Client list init. */
|
2003-06-15 03:28:29 +02:00
|
|
|
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);
|
2003-05-25 13:43:52 +02:00
|
|
|
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);
|
2015-05-20 02:47:22 +02:00
|
|
|
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);
|
2015-11-23 19:05:03 +01:00
|
|
|
install_element (CONFIG_NODE, &no_config_table_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif /* HAVE_NETLINK */
|
|
|
|
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_forwarding_cmd);
|
|
|
|
install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd);
|
2004-02-11 23:42:16 +01:00
|
|
|
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 */
|
2007-05-02 18:05:35 +02:00
|
|
|
|
|
|
|
/* Route-map */
|
|
|
|
zebra_route_map_init ();
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2009-07-24 18:45:31 +02:00
|
|
|
|
|
|
|
/* Make zebra server socket, wiping any existing one (see bug #403). */
|
|
|
|
void
|
2011-11-25 15:51:48 +01:00
|
|
|
zebra_zserv_socket_init (char *path)
|
2009-07-24 18:45:31 +02:00
|
|
|
{
|
|
|
|
#ifdef HAVE_TCP_ZEBRA
|
|
|
|
zebra_serv ();
|
|
|
|
#else
|
2011-11-25 15:51:48 +01:00
|
|
|
zebra_serv_un (path ? path : ZEBRA_SERV_PATH);
|
2009-07-24 18:45:31 +02:00
|
|
|
#endif /* HAVE_TCP_ZEBRA */
|
|
|
|
}
|