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.
|
|
|
|
*
|
2017-05-13 10:25:29 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; see the file COPYING; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2002-12-13 21:15:29 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "thread.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "memory.h"
|
2015-05-29 05:48:31 +02:00
|
|
|
#include "zebra_memory.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#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"
|
2016-06-01 19:19:30 +02:00
|
|
|
#include "zebra/zebra_mpls.h"
|
2016-08-11 02:04:20 +02:00
|
|
|
#include "zebra/zebra_mroute.h"
|
2017-03-20 15:34:49 +01:00
|
|
|
#include "zebra/label_manager.h"
|
2017-05-15 07:38:26 +02:00
|
|
|
#include "zebra/zebra_vxlan.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);
|
2017-02-02 02:35:39 +01:00
|
|
|
client = 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
|
|
|
break;
|
|
|
|
case BUFFER_PENDING:
|
2017-05-05 23:22:25 +02:00
|
|
|
client->t_write = NULL;
|
|
|
|
thread_add_write(zebrad.master, zserv_flush_data, client, client->sock,
|
|
|
|
&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
|
|
|
break;
|
|
|
|
case BUFFER_EMPTY:
|
|
|
|
break;
|
2003-03-01 12:42:20 +01:00
|
|
|
}
|
2015-05-20 02:47:22 +02:00
|
|
|
|
2017-02-02 02:35:39 +01:00
|
|
|
if (client)
|
|
|
|
client->last_write_time = monotime(NULL);
|
2005-02-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* zserv.c: Must include network.h and buffer.h for non-blocking I/O.
Remove global message_queue and t_write (need separate buffering for
each client).
(zebra_server_dequeue,zebra_server_enqueue) Remove functions
related to old buggy buffering code.
(zserv_delayed_close) New thread callback function to delete a client.
(zserv_flush_data) New thread callback function to flush buffered
data to client.
(zebra_server_send_message) Rewritten to use buffer_write (so
buffering of writes and non-blocking I/O work properly).
(zsend_interface_add,zsend_interface_delete,zsend_interface_address,
zsend_interface_update) Return 0 instead of -1 if !client->ifinfo
(this is not really an error). Return value from
zebra_server_send_message.
(zsend_route_multipath,zsend_ipv4_nexthop_lookup,
zsend_ipv4_import_lookup) Return value from zebra_server_send_message.
(zsend_ipv6_nexthop_lookup) Fix scope to static, and return value
from zebra_server_send_message.
(zsend_router_id_update) Must use zebra_server_send_message instead
of deprecated writen function. Return 0 instead of -1 if this client
is not subscribed to router-id updates (since this is not really
an error).
(zread_interface_add) Change type to static int. If
zsend_interface_add fails or zsend_interface_address fails, return -1
immediately (since the client has had an I/O error).
(zread_interface_delete,zread_ipv4_add,zread_ipv4_delete,
zread_ipv6_add,zread_ipv6_delete,zread_router_id_delete) Return 0
to indicate success.
(zread_ipv4_nexthop_lookup) Return value from
zsend_ipv4_nexthop_lookup.
(zread_ipv4_import_lookup) Return value from zsend_ipv4_import_lookup.
(zebra_read_ipv6) Remove unused function.
(zread_ipv6_nexthop_lookup) Return value from
zsend_ipv6_nexthop_lookup.
(zread_router_id_add) Return value from zsend_router_id_update.
(zebra_client_close) Call buffer_free(client->wb) and
thread_cancel(client->t_suicide).
(zebra_client_create) Allocate client->wb using buffer_new.
(zebra_client_read) Support non-blocking I/O by using stream_read_try.
Use ZEBRA_HEADER_SIZE instead of 3.
(zebra_accept) Fix bug: reset accept thread at top. Make client
socket non-blocking using the set_nonblocking function.
(config_write_forwarding) Fix scope to static.
(zebra_init) Remove initialization code for old buggy write buffering.
* zserv.h: Add 2 new fields to struct zserv: struct buffer *wb
(to enable buffered writes with non-blocking I/), and
struct thread *t_suicide to support delayed close on I/O
errors.
* router-id.h: Remove prototypes for zread_router_id_add and
zread_router_id_delete (their scope should be static to zserv.c).
2005-02-28 21:52:15 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2003-03-01 12:42:20 +01:00
|
|
|
|
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
|
|
|
|
2017-03-20 15:34:49 +01:00
|
|
|
if (client->is_synchronous)
|
|
|
|
return 0;
|
|
|
|
|
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. */
|
2017-05-05 23:22:25 +02:00
|
|
|
client->t_suicide = NULL;
|
|
|
|
thread_add_event(zebrad.master, zserv_delayed_close, client, 0,
|
|
|
|
&client->t_suicide);
|
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 -1;
|
|
|
|
case BUFFER_EMPTY:
|
|
|
|
THREAD_OFF(client->t_write);
|
|
|
|
break;
|
|
|
|
case BUFFER_PENDING:
|
2017-04-25 00:33:25 +02:00
|
|
|
thread_add_write(zebrad.master, zserv_flush_data, client, client->sock,
|
|
|
|
&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
|
|
|
break;
|
|
|
|
}
|
2015-05-20 02:47:22 +02:00
|
|
|
|
2017-01-18 01:30:43 +01:00
|
|
|
client->last_write_time = monotime(NULL);
|
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);
|
2017-03-30 21:37:22 +02:00
|
|
|
stream_putl (s, ifp->speed);
|
2012-03-22 01:13:39 +01:00
|
|
|
stream_putl (s, ifp->mtu);
|
|
|
|
stream_putl (s, ifp->mtu6);
|
|
|
|
stream_putl (s, ifp->bandwidth);
|
2016-01-15 16:36:33 +01:00
|
|
|
stream_putl (s, ifp->ll_type);
|
2012-03-22 01:13:39 +01:00
|
|
|
stream_putl (s, ifp->hw_addr_len);
|
|
|
|
if (ifp->hw_addr_len)
|
|
|
|
stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
|
|
|
|
|
Update Traffic Engineering Support for OSPFD
NOTE: I am squashing several commits together because they
do not independently compile and we need this ability to
do any type of sane testing on the patches. Since this
series builds together I am doing this. -DBS
This new structure is the basis to get new link parameters for
Traffic Engineering from Zebra/interface layer to OSPFD and ISISD
for the support of Traffic Engineering
* lib/if.[c,h]: link parameters struture and get/set functions
* lib/command.[c,h]: creation of a new link-node
* lib/zclient.[c,h]: modification to the ZBUS message to convey the
link parameters structure
* lib/zebra.h: New ZBUS message
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Add support for IEEE 754 format
* lib/stream.[c,h]: Add stream_get{f,d} and stream_put{f,d}) demux and muxers to
safely convert between big-endian IEEE-754 single and double binary
format, as used in IETF RFCs, and C99. Implementation depends on host
using __STDC_IEC_559__, which should be everything we care about. Should
correctly error out otherwise.
* lib/network.[c,h]: Add ntohf and htonf converter
* lib/memtypes.c: Add new memeory type for Traffic Engineering support
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Add link parameters support to Zebra
* zebra/interface.c:
- Add new link-params CLI commands
- Add new functions to set/get link parameters for interface
* zebra/redistribute.[c,h]: Add new function to propagate link parameters
to routing daemon (essentially OSPFD and ISISD) for Traffic Engineering.
* zebra/redistribute_null.c: Add new function
zebra_interface_parameters_update()
* zebra/zserv.[c,h]: Add new functions to send link parameters
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Add support of new link-params CLI to vtysh
In vtysh_config.c/vtysh_config_parse_line(), it is not possible to continue
to use the ordered version for adding line i.e. config_add_line_uniq() to print
Interface CLI commands as it completely break the new LINK_PARAMS_NODE.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Update Traffic Engineering support for OSPFD
These patches update original code to RFC3630 (OSPF-TE) and add support of
RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support
of RFC6827 (ASON - GMPLS).
* ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering
* ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392
* ospfd/ospf_packet.c: Update checking of OSPF_OPTION
* ospfd/ospf_vty.[c,h]: Update ospf_str2area_id
* ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get
Link Parameters information from the interface to populate Traffic Engineering
metrics
* ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN)
* ospfd/ospf_te.[c,h]: Major modifications to update the code to new
link parameters structure and new RFCs
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
tmp
2016-04-19 16:21:46 +02:00
|
|
|
/* Then, Traffic Engineering parameters if any */
|
|
|
|
if (HAS_LINK_PARAMS(ifp) && IS_LINK_PARAMS_SET(ifp->link_params))
|
|
|
|
{
|
|
|
|
stream_putc (s, 1);
|
|
|
|
zebra_interface_link_params_write (s, ifp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
stream_putc (s, 0);
|
|
|
|
|
2012-03-22 01:13:39 +01:00
|
|
|
/* 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
|
|
|
{
|
2017-05-17 22:20:29 +02:00
|
|
|
struct vrf_data data;
|
|
|
|
|
|
|
|
data.l.table_id = zvrf->table_id;
|
|
|
|
/* Pass the tableid */
|
|
|
|
stream_put (s, &data, sizeof (struct vrf_data));
|
2016-02-01 19:55:42 +01:00
|
|
|
/* Interface information. */
|
2016-10-30 22:50:26 +01:00
|
|
|
stream_put (s, zvrf_name (zvrf), 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-10-30 22:50:26 +01:00
|
|
|
zserv_create_header (s, ZEBRA_VRF_ADD, zvrf_id (zvrf));
|
2016-03-22 21:37:17 +01:00
|
|
|
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-10-30 22:50:26 +01:00
|
|
|
zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf_id (zvrf));
|
2016-03-22 21:37:17 +01:00
|
|
|
zserv_encode_vrf (s, zvrf);
|
2016-02-01 19:55:42 +01:00
|
|
|
|
|
|
|
client->vrfdel_cnt++;
|
|
|
|
return zebra_server_send_message (client);
|
|
|
|
}
|
|
|
|
|
Update Traffic Engineering Support for OSPFD
NOTE: I am squashing several commits together because they
do not independently compile and we need this ability to
do any type of sane testing on the patches. Since this
series builds together I am doing this. -DBS
This new structure is the basis to get new link parameters for
Traffic Engineering from Zebra/interface layer to OSPFD and ISISD
for the support of Traffic Engineering
* lib/if.[c,h]: link parameters struture and get/set functions
* lib/command.[c,h]: creation of a new link-node
* lib/zclient.[c,h]: modification to the ZBUS message to convey the
link parameters structure
* lib/zebra.h: New ZBUS message
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Add support for IEEE 754 format
* lib/stream.[c,h]: Add stream_get{f,d} and stream_put{f,d}) demux and muxers to
safely convert between big-endian IEEE-754 single and double binary
format, as used in IETF RFCs, and C99. Implementation depends on host
using __STDC_IEC_559__, which should be everything we care about. Should
correctly error out otherwise.
* lib/network.[c,h]: Add ntohf and htonf converter
* lib/memtypes.c: Add new memeory type for Traffic Engineering support
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Add link parameters support to Zebra
* zebra/interface.c:
- Add new link-params CLI commands
- Add new functions to set/get link parameters for interface
* zebra/redistribute.[c,h]: Add new function to propagate link parameters
to routing daemon (essentially OSPFD and ISISD) for Traffic Engineering.
* zebra/redistribute_null.c: Add new function
zebra_interface_parameters_update()
* zebra/zserv.[c,h]: Add new functions to send link parameters
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Add support of new link-params CLI to vtysh
In vtysh_config.c/vtysh_config_parse_line(), it is not possible to continue
to use the ordered version for adding line i.e. config_add_line_uniq() to print
Interface CLI commands as it completely break the new LINK_PARAMS_NODE.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Update Traffic Engineering support for OSPFD
These patches update original code to RFC3630 (OSPF-TE) and add support of
RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support
of RFC6827 (ASON - GMPLS).
* ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering
* ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392
* ospfd/ospf_packet.c: Update checking of OSPF_OPTION
* ospfd/ospf_vty.[c,h]: Update ospf_str2area_id
* ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get
Link Parameters information from the interface to populate Traffic Engineering
metrics
* ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN)
* ospfd/ospf_te.[c,h]: Major modifications to update the code to new
link parameters structure and new RFCs
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
tmp
2016-04-19 16:21:46 +02:00
|
|
|
int
|
|
|
|
zsend_interface_link_params (struct zserv *client, struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
|
|
|
|
/* Check this client need interface information. */
|
|
|
|
if (! client->ifinfo)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!ifp->link_params)
|
|
|
|
return 0;
|
|
|
|
s = client->obuf;
|
|
|
|
stream_reset (s);
|
|
|
|
|
|
|
|
zserv_create_header (s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id);
|
|
|
|
|
|
|
|
/* Add Interface Index */
|
|
|
|
stream_putl (s, ifp->ifindex);
|
|
|
|
|
|
|
|
/* Then TE Link Parameters */
|
|
|
|
if (zebra_interface_link_params_write (s, ifp) == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Write packet size. */
|
|
|
|
stream_putw_at (s, 0, stream_get_endp (s));
|
|
|
|
|
|
|
|
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
|
2016-10-06 14:18:41 +02:00
|
|
|
zsend_redistribute_route (int add, struct zserv *client, struct prefix *p,
|
2017-06-01 13:26:25 +02:00
|
|
|
struct prefix *src_p, struct route_entry *re)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-10-06 14:18:41 +02:00
|
|
|
afi_t afi;
|
|
|
|
int cmd;
|
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;
|
|
|
|
|
2016-10-06 14:18:41 +02:00
|
|
|
afi = family2afi (p->family);
|
|
|
|
if (add)
|
|
|
|
{
|
|
|
|
switch (afi)
|
|
|
|
{
|
|
|
|
case AFI_IP:
|
|
|
|
cmd = ZEBRA_REDISTRIBUTE_IPV4_ADD;
|
|
|
|
client->redist_v4_add_cnt++;
|
|
|
|
break;
|
|
|
|
case AFI_IP6:
|
|
|
|
cmd = ZEBRA_REDISTRIBUTE_IPV6_ADD;
|
|
|
|
client->redist_v6_add_cnt++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (afi)
|
|
|
|
{
|
|
|
|
case AFI_IP:
|
|
|
|
cmd = ZEBRA_REDISTRIBUTE_IPV4_DEL;
|
|
|
|
client->redist_v4_del_cnt++;
|
|
|
|
break;
|
|
|
|
case AFI_IP6:
|
|
|
|
cmd = ZEBRA_REDISTRIBUTE_IPV6_DEL;
|
|
|
|
client->redist_v6_del_cnt++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
*: 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
|
|
|
|
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));
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
zserv_create_header (s, cmd, re->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
|
|
|
|
2006-01-16 02:54:02 +01:00
|
|
|
/* Put type and nexthop. */
|
2017-06-01 13:26:25 +02:00
|
|
|
stream_putc (s, re->type);
|
|
|
|
stream_putw (s, re->instance);
|
|
|
|
stream_putl (s, re->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);
|
|
|
|
|
2016-12-05 20:05:30 +01:00
|
|
|
if (src_p)
|
|
|
|
{
|
|
|
|
SET_FLAG (zapi_flags, ZAPI_MESSAGE_SRCPFX);
|
|
|
|
psize = PSIZE (src_p->prefixlen);
|
|
|
|
stream_putc (s, src_p->prefixlen);
|
|
|
|
stream_write (s, (u_char *) & src_p->u.prefix, psize);
|
|
|
|
}
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-10-21 06:38:38 +02:00
|
|
|
/* We don't send any nexthops when there's a multipath */
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->nexthop_active_num > 1 && client->proto != ZEBRA_ROUTE_LDP)
|
2015-10-21 06:38:38 +02:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-01-15 16:36:31 +01:00
|
|
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
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);
|
|
|
|
|
2016-03-01 19:31:28 +01:00
|
|
|
/* ldpd needs all nexthops */
|
|
|
|
if (client->proto != ZEBRA_ROUTE_LDP)
|
2017-02-06 14:57:34 +01:00
|
|
|
break;
|
2004-05-09 11:09:59 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-09-21 18:38:34 +02:00
|
|
|
/* Distance */
|
2017-02-06 14:57:34 +01:00
|
|
|
SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
|
2017-06-01 13:26:25 +02:00
|
|
|
stream_putc (s, re->distance);
|
2016-09-21 18:38:34 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Metric */
|
2017-02-06 14:57:34 +01:00
|
|
|
SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
|
2017-06-01 13:26:25 +02:00
|
|
|
stream_putl (s, re->metric);
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2016-09-21 18:38:34 +02:00
|
|
|
/* Tag */
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re->tag)
|
2017-02-06 14:57:34 +01:00
|
|
|
{
|
|
|
|
SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG);
|
2017-06-01 13:26:25 +02:00
|
|
|
stream_putl(s, re->tag);
|
2017-02-06 14:57:34 +01:00
|
|
|
}
|
2015-10-21 06:38:38 +02:00
|
|
|
|
2016-09-21 18:38:34 +02:00
|
|
|
/* MTU */
|
2017-02-06 14:57:34 +01:00
|
|
|
SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU);
|
2017-06-01 13:26:25 +02:00
|
|
|
stream_putl (s, re->mtu);
|
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
|
|
|
}
|
|
|
|
|
2016-09-14 14:23:27 +02:00
|
|
|
static int
|
|
|
|
zsend_write_nexthop (struct stream *s, struct nexthop *nexthop)
|
|
|
|
{
|
|
|
|
stream_putc (s, nexthop->type);
|
|
|
|
switch (nexthop->type)
|
|
|
|
{
|
|
|
|
case NEXTHOP_TYPE_IPV4:
|
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
|
|
|
stream_put_in_addr (s, &nexthop->gate.ipv4);
|
|
|
|
stream_putl (s, nexthop->ifindex);
|
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6:
|
|
|
|
stream_put (s, &nexthop->gate.ipv6, 16);
|
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
|
|
|
stream_put (s, &nexthop->gate.ipv6, 16);
|
|
|
|
stream_putl (s, nexthop->ifindex);
|
|
|
|
break;
|
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
|
|
|
stream_putl (s, nexthop->ifindex);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* do nothing */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
2017-01-18 01:30:43 +01:00
|
|
|
client->nh_reg_time = monotime(NULL);
|
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-10-30 22:50:26 +01:00
|
|
|
rnh = zebra_add_rnh(&p, zvrf_id (zvrf), 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-10-30 22:50:26 +01:00
|
|
|
zebra_add_rnh_client(rnh, client, type, zvrf_id (zvrf));
|
2015-05-20 03:04:20 +02:00
|
|
|
/* Anything not AF_INET/INET6 has been filtered out above */
|
2016-10-30 22:50:26 +01:00
|
|
|
zebra_evaluate_rnh(zvrf_id (zvrf), 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-10-30 22:50:26 +01:00
|
|
|
rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type);
|
2015-05-20 02:40:34 +02:00
|
|
|
if (rnh)
|
2015-05-20 02:47:22 +02:00
|
|
|
{
|
2017-01-18 01:30:43 +01:00
|
|
|
client->nh_dereg_time = monotime(NULL);
|
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;
|
|
|
|
}
|
|
|
|
|
2017-05-10 15:41:07 +02:00
|
|
|
#define ZEBRA_MIN_FEC_LENGTH 5
|
2017-04-15 19:25:03 +02:00
|
|
|
|
2017-02-01 19:10:56 +01:00
|
|
|
/* FEC register */
|
|
|
|
static int
|
|
|
|
zserv_fec_register (struct zserv *client, int sock, u_short length)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
u_short l = 0;
|
|
|
|
struct prefix p;
|
2017-03-09 18:55:54 +01:00
|
|
|
u_int16_t flags;
|
|
|
|
u_int32_t label_index = MPLS_INVALID_LABEL_INDEX;
|
2017-02-01 19:10:56 +01:00
|
|
|
|
|
|
|
s = client->ibuf;
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
if (!zvrf)
|
|
|
|
return 0; // unexpected
|
|
|
|
|
2017-04-15 19:25:03 +02:00
|
|
|
/*
|
|
|
|
* The minimum amount of data that can be sent for one fec
|
|
|
|
* registration
|
|
|
|
*/
|
|
|
|
if (length < ZEBRA_MIN_FEC_LENGTH)
|
|
|
|
{
|
|
|
|
zlog_err ("fec_register: Received a fec register of length %d, it is of insufficient size to properly decode",
|
|
|
|
length);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-02-01 19:10:56 +01:00
|
|
|
while (l < length)
|
|
|
|
{
|
2017-03-09 18:55:54 +01:00
|
|
|
flags = stream_getw(s);
|
2017-02-01 19:10:56 +01:00
|
|
|
p.family = stream_getw(s);
|
2017-04-15 19:25:03 +02:00
|
|
|
if (p.family != AF_INET &&
|
|
|
|
p.family != AF_INET6)
|
|
|
|
{
|
|
|
|
zlog_err ("fec_register: Received unknown family type %d\n",
|
|
|
|
p.family);
|
|
|
|
return -1;
|
|
|
|
}
|
2017-02-01 19:10:56 +01:00
|
|
|
p.prefixlen = stream_getc(s);
|
|
|
|
l += 5;
|
|
|
|
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
|
|
|
|
l += PSIZE(p.prefixlen);
|
2017-03-09 18:55:54 +01:00
|
|
|
if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX)
|
|
|
|
{
|
|
|
|
label_index = stream_getl(s);
|
|
|
|
l += 4;
|
|
|
|
}
|
2017-06-16 21:12:57 +02:00
|
|
|
else
|
|
|
|
label_index = MPLS_INVALID_LABEL_INDEX;
|
2017-03-09 18:55:54 +01:00
|
|
|
zebra_mpls_fec_register (zvrf, &p, label_index, client);
|
2017-02-01 19:10:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FEC unregister */
|
|
|
|
static int
|
|
|
|
zserv_fec_unregister (struct zserv *client, int sock, u_short length)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
u_short l = 0;
|
|
|
|
struct prefix p;
|
2017-03-10 19:34:02 +01:00
|
|
|
//u_int16_t flags;
|
2017-02-01 19:10:56 +01:00
|
|
|
|
|
|
|
s = client->ibuf;
|
|
|
|
zvrf = vrf_info_lookup(VRF_DEFAULT);
|
|
|
|
if (!zvrf)
|
|
|
|
return 0; // unexpected
|
|
|
|
|
2017-04-15 19:25:03 +02:00
|
|
|
/*
|
|
|
|
* The minimum amount of data that can be sent for one
|
|
|
|
* fec unregistration
|
|
|
|
*/
|
|
|
|
if (length < ZEBRA_MIN_FEC_LENGTH)
|
|
|
|
{
|
|
|
|
zlog_err ("fec_unregister: Received a fec unregister of length %d, it is of insufficient size to properly decode",
|
|
|
|
length);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-02-01 19:10:56 +01:00
|
|
|
while (l < length)
|
|
|
|
{
|
2017-03-10 19:34:02 +01:00
|
|
|
//flags = stream_getw(s);
|
|
|
|
(void)stream_getw(s);
|
2017-02-01 19:10:56 +01:00
|
|
|
p.family = stream_getw(s);
|
2017-04-15 19:25:03 +02:00
|
|
|
if (p.family != AF_INET &&
|
|
|
|
p.family != AF_INET6)
|
|
|
|
{
|
|
|
|
zlog_err ("fec_unregister: Received unknown family type %d\n",
|
|
|
|
p.family);
|
|
|
|
return -1;
|
|
|
|
}
|
2017-02-01 19:10:56 +01:00
|
|
|
p.prefixlen = stream_getc(s);
|
|
|
|
l += 5;
|
|
|
|
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
|
|
|
|
l += PSIZE(p.prefixlen);
|
|
|
|
zebra_mpls_fec_unregister (zvrf, &p, client);
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2017-06-01 13:26:25 +02:00
|
|
|
zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struct route_entry *re, 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. */
|
2016-10-30 22:50:26 +01:00
|
|
|
zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id (zvrf));
|
2014-07-01 20:15:52 +02:00
|
|
|
stream_put_in_addr (s, &addr);
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (re)
|
2014-07-01 20:15:52 +02:00
|
|
|
{
|
2017-06-01 13:26:25 +02:00
|
|
|
stream_putc (s, re->distance);
|
|
|
|
stream_putl (s, re->metric);
|
2014-07-01 20:15:52 +02:00
|
|
|
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. */
|
2017-06-01 13:26:25 +02:00
|
|
|
for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
|
2016-01-15 16:36:31 +01:00
|
|
|
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
2016-09-14 14:23:27 +02:00
|
|
|
num += zsend_write_nexthop (s, nexthop);
|
2014-07-01 20:15:52 +02:00
|
|
|
|
|
|
|
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-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
|
|
|
{
|
2016-10-29 18:37:11 +02:00
|
|
|
struct vrf *vrf;
|
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;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct interface *ifp;
|
|
|
|
|
|
|
|
/* Interface information is needed. */
|
2016-10-30 22:50:26 +01:00
|
|
|
vrf_bitmap_set (client->ifinfo, zvrf_id (zvrf));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-10-29 18:37:11 +02:00
|
|
|
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-10-29 18:37:11 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (vrf->iflist, ifnode, ifnnode, ifp))
|
2016-04-22 02:12:26 +02:00
|
|
|
{
|
|
|
|
/* 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-10-30 22:50:26 +01:00
|
|
|
vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf));
|
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
|
|
|
{
|
2016-11-04 00:59:19 +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",
|
2016-11-04 00:59:19 +01:00
|
|
|
caller, buff, nexthop_num, multipath_num);
|
2015-09-16 14:30:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* This function support multiple nexthop. */
|
2004-05-09 11:09:59 +02:00
|
|
|
/*
|
2017-06-01 13:26:25 +02:00
|
|
|
* Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update re and
|
2004-05-09 11:09:59 +02:00
|
|
|
* 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;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2016-08-24 10:01:20 +02:00
|
|
|
struct prefix p;
|
2002-12-13 21:15:29 +01:00
|
|
|
u_char message;
|
2017-02-02 18:58:33 +01:00
|
|
|
struct in_addr nhop_addr;
|
2002-12-13 21:15:29 +01:00
|
|
|
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;
|
2017-02-02 18:58:33 +01:00
|
|
|
mpls_label_t label;
|
|
|
|
struct nexthop *nexthop;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Get input stream. */
|
|
|
|
s = client->ibuf;
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
/* Allocate new re. */
|
|
|
|
re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
|
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
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Type, flags, message. */
|
2017-06-01 13:26:25 +02:00
|
|
|
re->type = stream_getc (s);
|
|
|
|
re->instance = stream_getw (s);
|
|
|
|
re->flags = stream_getl (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);
|
2017-06-01 13:26:25 +02:00
|
|
|
re->uptime = time (NULL);
|
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);
|
2016-08-24 10:01:20 +02:00
|
|
|
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-22 11:40:02 +02:00
|
|
|
/* VRF ID */
|
2017-06-01 13:26:25 +02:00
|
|
|
re->vrf_id = zvrf_id (zvrf);
|
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)
|
|
|
|
{
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
2002-12-13 21:15:29 +01:00
|
|
|
ifindex = stream_getl (s);
|
2017-06-01 13:26:25 +02:00
|
|
|
route_entry_nexthop_ifindex_add (re, ifindex);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IPV4:
|
2017-02-02 18:58:33 +01:00
|
|
|
nhop_addr.s_addr = stream_get_ipv4 (s);
|
2017-06-01 13:26:25 +02:00
|
|
|
nexthop = route_entry_nexthop_ipv4_add (re, &nhop_addr, NULL);
|
2017-02-02 18:58:33 +01:00
|
|
|
/* For labeled-unicast, each nexthop is followed by label. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
|
|
|
|
{
|
|
|
|
label = (mpls_label_t)stream_getl (s);
|
|
|
|
nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &label);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
2017-02-02 18:58:33 +01:00
|
|
|
nhop_addr.s_addr = stream_get_ipv4 (s);
|
2012-07-07 17:06:13 +02:00
|
|
|
ifindex = stream_getl (s);
|
2017-06-01 13:26:25 +02:00
|
|
|
route_entry_nexthop_ipv4_ifindex_add (re, &nhop_addr, NULL, ifindex);
|
2012-07-07 17:06:13 +02:00
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_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;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_BLACKHOLE:
|
2017-06-01 13:26:25 +02:00
|
|
|
route_entry_nexthop_blackhole_add (re);
|
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))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->distance = stream_getc (s);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Metric. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->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))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->tag = stream_getl (s);
|
2015-05-20 02:46:33 +02:00
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
re->tag = 0;
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2015-11-02 15:50:07 +01:00
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->mtu = stream_getl (s);
|
2015-11-02 15:50:07 +01:00
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
re->mtu = 0;
|
2015-11-02 15:50:07 +01:00
|
|
|
|
2006-07-27 18:11:02 +02:00
|
|
|
/* Table */
|
2017-06-01 13:26:25 +02:00
|
|
|
re->table = zvrf->table_id;
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
ret = rib_add_multipath (AFI_IP, safi, &p, NULL, re);
|
2015-05-20 02:47:22 +02:00
|
|
|
|
|
|
|
/* 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;
|
2016-08-24 07:39:08 +02:00
|
|
|
struct in_addr nexthop;
|
|
|
|
union g_addr *nexthop_p;
|
2002-12-13 21:15:29 +01:00
|
|
|
unsigned long ifindex;
|
2016-08-24 07:39:08 +02:00
|
|
|
struct prefix p;
|
2002-12-13 21:15:29 +01:00
|
|
|
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);
|
2016-09-16 21:55:37 +02:00
|
|
|
api.flags = stream_getl (s);
|
2002-12-13 21:15:29 +01:00
|
|
|
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. */
|
2017-02-03 12:30:59 +01:00
|
|
|
memset (&p, 0, sizeof (struct prefix));
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
|
|
|
p.prefixlen = stream_getc (s);
|
2016-08-24 07:39:08 +02:00
|
|
|
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* 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)
|
|
|
|
{
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
2002-12-13 21:15:29 +01:00
|
|
|
ifindex = stream_getl (s);
|
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IPV4:
|
2002-12-13 21:15:29 +01:00
|
|
|
nexthop.s_addr = stream_get_ipv4 (s);
|
2017-02-02 18:58:33 +01:00
|
|
|
/* For labeled-unicast, each nexthop is followed by label, but
|
|
|
|
* we don't care for delete.
|
|
|
|
*/
|
|
|
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_LABEL))
|
|
|
|
stream_forward_getp (s, sizeof(u_int32_t));
|
2016-08-24 07:39:08 +02:00
|
|
|
nexthop_p = (union g_addr *)&nexthop;
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
2012-07-07 17:06:13 +02:00
|
|
|
nexthop.s_addr = stream_get_ipv4 (s);
|
2016-08-24 07:39:08 +02:00
|
|
|
nexthop_p = (union g_addr *)&nexthop;
|
2012-07-07 17:06:13 +02:00
|
|
|
ifindex = stream_getl (s);
|
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_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))
|
2016-10-01 20:42:34 +02:00
|
|
|
api.tag = stream_getl (s);
|
2015-05-20 02:46:33 +02:00
|
|
|
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
|
|
|
|
2016-10-30 22:50:26 +01:00
|
|
|
rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance,
|
2014-04-24 17:41:43 +02:00
|
|
|
api.flags, &p, NULL, nexthop_p, ifindex, table_id);
|
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
|
|
|
}
|
|
|
|
|
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;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2014-07-01 20:15:52 +02:00
|
|
|
|
|
|
|
addr.s_addr = stream_get_ipv4 (client->ibuf);
|
2017-06-01 13:26:25 +02:00
|
|
|
re = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL);
|
|
|
|
return zsend_ipv4_nexthop_lookup_mrib (client, addr, re, zvrf);
|
2014-07-01 20:15:52 +02: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
|
|
|
{
|
2016-11-04 00:59:19 +01:00
|
|
|
unsigned int i;
|
2015-06-11 18:19:12 +02:00
|
|
|
struct stream *s;
|
2017-05-24 20:31:10 +02:00
|
|
|
struct in6_addr nhop_addr;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2015-06-11 18:19:12 +02:00
|
|
|
u_char message;
|
|
|
|
u_char nexthop_num;
|
|
|
|
u_char nexthop_type;
|
2016-08-24 10:01:20 +02:00
|
|
|
struct prefix p;
|
2015-06-11 18:19:12 +02:00
|
|
|
safi_t safi;
|
|
|
|
static struct in6_addr nexthops[MULTIPATH_NUM];
|
|
|
|
static unsigned int ifindices[MULTIPATH_NUM];
|
|
|
|
int ret;
|
2017-05-24 20:31:10 +02:00
|
|
|
static mpls_label_t labels[MULTIPATH_NUM];
|
|
|
|
mpls_label_t label;
|
|
|
|
struct nexthop *nexthop;
|
2015-06-11 18:19:12 +02:00
|
|
|
|
|
|
|
/* Get input stream. */
|
|
|
|
s = client->ibuf;
|
|
|
|
|
2017-05-24 20:31:10 +02:00
|
|
|
memset (&nhop_addr, 0, sizeof (struct in6_addr));
|
2015-06-11 18:19:12 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
/* Allocate new re. */
|
|
|
|
re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
|
2015-06-11 18:19:12 +02:00
|
|
|
|
|
|
|
/* Type, flags, message. */
|
2017-06-01 13:26:25 +02:00
|
|
|
re->type = stream_getc (s);
|
|
|
|
re->instance = stream_getw (s);
|
|
|
|
re->flags = stream_getl (s);
|
2015-06-11 18:19:12 +02:00
|
|
|
message = stream_getc (s);
|
|
|
|
safi = stream_getw (s);
|
2017-06-01 13:26:25 +02:00
|
|
|
re->uptime = time (NULL);
|
2015-06-11 18:19:12 +02:00
|
|
|
|
|
|
|
/* IPv4 prefix. */
|
|
|
|
memset (&p, 0, sizeof (struct prefix_ipv4));
|
|
|
|
p.family = AF_INET;
|
|
|
|
p.prefixlen = stream_getc (s);
|
2016-08-24 10:01:20 +02:00
|
|
|
stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen));
|
2015-06-11 18:19:12 +02:00
|
|
|
|
2016-04-06 23:07:05 +02:00
|
|
|
/* VRF ID */
|
2017-06-01 13:26:25 +02:00
|
|
|
re->vrf_id = zvrf_id (zvrf);
|
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
|
2017-06-01 13:26:25 +02:00
|
|
|
* to the re to ensure that IPv6 multipathing works; need to coalesce
|
2015-06-11 18:19:12 +02:00
|
|
|
* these. Clients should send the same number of paired set of
|
|
|
|
* next-hop-addr/next-hop-ifindices. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
|
|
|
|
{
|
2016-11-04 00:59:19 +01:00
|
|
|
unsigned int nh_count = 0;
|
|
|
|
unsigned int if_count = 0;
|
|
|
|
unsigned int max_nh_if = 0;
|
2015-06-11 18:19:12 +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);
|
2015-06-11 18:19:12 +02:00
|
|
|
for (i = 0; i < nexthop_num; i++)
|
|
|
|
{
|
|
|
|
nexthop_type = stream_getc (s);
|
|
|
|
|
|
|
|
switch (nexthop_type)
|
|
|
|
{
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IPV6:
|
2017-05-24 20:31:10 +02:00
|
|
|
stream_get (&nhop_addr, s, 16);
|
|
|
|
if (nh_count < MULTIPATH_NUM)
|
|
|
|
{
|
|
|
|
/* For labeled-unicast, each nexthop is followed by label. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
|
|
|
|
{
|
|
|
|
label = (mpls_label_t)stream_getl (s);
|
|
|
|
labels[nh_count] = label;
|
|
|
|
}
|
|
|
|
nexthops[nh_count] = nhop_addr;
|
|
|
|
nh_count++;
|
|
|
|
}
|
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
2016-11-04 00:59:19 +01:00
|
|
|
if (if_count < multipath_num) {
|
2015-06-11 18:19:12 +02:00
|
|
|
ifindices[if_count++] = stream_getl (s);
|
|
|
|
}
|
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_BLACKHOLE:
|
2017-06-01 13:26:25 +02:00
|
|
|
route_entry_nexthop_blackhole_add (re);
|
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])) {
|
2017-05-24 20:31:10 +02:00
|
|
|
if ((i < if_count) && ifindices[i])
|
2017-06-01 13:26:25 +02:00
|
|
|
nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &nexthops[i], ifindices[i]);
|
2017-05-24 20:31:10 +02:00
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
nexthop = route_entry_nexthop_ipv6_add (re, &nexthops[i]);
|
2017-05-24 20:31:10 +02:00
|
|
|
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
|
|
|
|
nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]);
|
2015-06-11 18:19:12 +02:00
|
|
|
}
|
|
|
|
else {
|
2017-05-24 20:31:10 +02:00
|
|
|
if ((i < if_count) && ifindices[i])
|
2017-06-01 13:26:25 +02:00
|
|
|
route_entry_nexthop_ifindex_add (re, ifindices[i]);
|
2017-05-24 20:31:10 +02:00
|
|
|
}
|
2015-06-11 18:19:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Distance. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->distance = stream_getc (s);
|
2015-06-11 18:19:12 +02:00
|
|
|
|
|
|
|
/* Metric. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->metric = stream_getl (s);
|
2015-06-11 18:19:12 +02:00
|
|
|
|
|
|
|
/* Tag */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->tag = stream_getl (s);
|
2015-06-11 18:19:12 +02:00
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
re->tag = 0;
|
2015-06-11 18:19:12 +02:00
|
|
|
|
2015-11-02 15:50:07 +01:00
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->mtu = stream_getl (s);
|
2015-11-02 15:50:07 +01:00
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
re->mtu = 0;
|
2015-11-02 15:50:07 +01:00
|
|
|
|
2015-06-11 18:19:12 +02:00
|
|
|
/* Table */
|
2017-06-01 13:26:25 +02:00
|
|
|
re->table = zvrf->table_id;
|
2016-02-01 19:55:42 +01:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, re);
|
2015-06-11 18:19:12 +02:00
|
|
|
/* 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
|
|
|
{
|
2016-11-04 00:59:19 +01:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct stream *s;
|
2017-02-02 18:58:33 +01:00
|
|
|
struct in6_addr nhop_addr;
|
2017-06-01 13:26:25 +02:00
|
|
|
struct route_entry *re;
|
2015-05-20 02:24:43 +02:00
|
|
|
u_char message;
|
|
|
|
u_char nexthop_num;
|
|
|
|
u_char nexthop_type;
|
2016-08-24 10:01:20 +02:00
|
|
|
struct prefix p;
|
2014-04-24 17:41:43 +02:00
|
|
|
struct prefix_ipv6 src_p, *src_pp;
|
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;
|
2017-02-02 18:58:33 +01:00
|
|
|
static mpls_label_t labels[MULTIPATH_NUM];
|
|
|
|
mpls_label_t label;
|
|
|
|
struct nexthop *nexthop;
|
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
|
|
|
|
2017-02-02 18:58:33 +01:00
|
|
|
memset (&nhop_addr, 0, sizeof (struct in6_addr));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
/* Allocate new re. */
|
|
|
|
re = XCALLOC (MTYPE_RE, sizeof (struct route_entry));
|
2015-05-20 02:24:43 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Type, flags, message. */
|
2017-06-01 13:26:25 +02:00
|
|
|
re->type = stream_getc (s);
|
|
|
|
re->instance = stream_getw (s);
|
|
|
|
re->flags = stream_getl (s);
|
2015-05-20 02:24:43 +02:00
|
|
|
message = stream_getc (s);
|
|
|
|
safi = stream_getw (s);
|
2017-06-01 13:26:25 +02:00
|
|
|
re->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);
|
2016-08-24 10:01:20 +02:00
|
|
|
stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2014-04-24 17:41:43 +02:00
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_SRCPFX))
|
|
|
|
{
|
|
|
|
memset (&src_p, 0, sizeof (struct prefix_ipv6));
|
|
|
|
src_p.family = AF_INET6;
|
|
|
|
src_p.prefixlen = stream_getc (s);
|
|
|
|
stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
|
|
|
|
src_pp = &src_p;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
src_pp = NULL;
|
|
|
|
|
2015-05-20 02:24:43 +02:00
|
|
|
/* We need to give nh-addr, nh-ifindex with the same next-hop object
|
2017-06-01 13:26:25 +02:00
|
|
|
* to the re to ensure that IPv6 multipathing works; need to coalesce
|
2015-05-20 02:24:43 +02:00
|
|
|
* 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
|
|
|
{
|
2016-11-04 00:59:19 +01:00
|
|
|
unsigned int nh_count = 0;
|
|
|
|
unsigned int if_count = 0;
|
|
|
|
unsigned 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)
|
|
|
|
{
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IPV6:
|
2017-02-02 18:58:33 +01:00
|
|
|
stream_get (&nhop_addr, s, 16);
|
|
|
|
if (nh_count < MULTIPATH_NUM)
|
|
|
|
{
|
|
|
|
/* For labeled-unicast, each nexthop is followed by label. */
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
|
|
|
|
{
|
|
|
|
label = (mpls_label_t)stream_getl (s);
|
2017-05-30 00:41:40 +02:00
|
|
|
labels[nh_count] = label;
|
2017-02-02 18:58:33 +01:00
|
|
|
}
|
|
|
|
nexthops[nh_count++] = nhop_addr;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
2016-11-04 00:59:19 +01:00
|
|
|
if (if_count < multipath_num) {
|
2015-05-20 02:24:43 +02:00
|
|
|
ifindices[if_count++] = stream_getl (s);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_BLACKHOLE:
|
2017-06-01 13:26:25 +02:00
|
|
|
route_entry_nexthop_blackhole_add (re);
|
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])
|
2017-06-01 13:26:25 +02:00
|
|
|
nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &nexthops[i], ifindices[i]);
|
2015-11-10 02:02:26 +01:00
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
nexthop = route_entry_nexthop_ipv6_add (re, &nexthops[i]);
|
2017-02-02 18:58:33 +01:00
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL))
|
|
|
|
nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]);
|
2015-05-20 02:24:43 +02:00
|
|
|
}
|
|
|
|
else {
|
2015-11-10 02:02:26 +01:00
|
|
|
if ((i < if_count) && ifindices[i])
|
2017-06-01 13:26:25 +02:00
|
|
|
route_entry_nexthop_ifindex_add (re, 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))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->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))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->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))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->tag = stream_getl (s);
|
2015-05-20 02:46:33 +02:00
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
re->tag = 0;
|
2015-11-02 15:50:07 +01:00
|
|
|
|
|
|
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU))
|
2017-06-01 13:26:25 +02:00
|
|
|
re->mtu = stream_getl (s);
|
2015-11-02 15:50:07 +01:00
|
|
|
else
|
2017-06-01 13:26:25 +02:00
|
|
|
re->mtu = 0;
|
2015-05-20 02:46:33 +02:00
|
|
|
|
2016-04-06 23:07:05 +02:00
|
|
|
/* VRF ID */
|
2017-06-01 13:26:25 +02:00
|
|
|
re->vrf_id = zvrf_id (zvrf);
|
|
|
|
re->table = zvrf->table_id;
|
2016-04-06 23:07:05 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, re);
|
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;
|
2016-11-13 04:12:13 +01:00
|
|
|
union g_addr *pnexthop = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
unsigned long ifindex;
|
2016-08-24 07:39:08 +02:00
|
|
|
struct prefix p;
|
2014-04-24 17:41:43 +02:00
|
|
|
struct prefix_ipv6 src_p, *src_pp;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
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);
|
2016-09-16 21:55:37 +02:00
|
|
|
api.flags = stream_getl (s);
|
2002-12-13 21:15:29 +01:00
|
|
|
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);
|
2016-08-24 07:39:08 +02:00
|
|
|
stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2014-04-24 17:41:43 +02:00
|
|
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
|
|
|
|
{
|
|
|
|
memset (&src_p, 0, sizeof (struct prefix_ipv6));
|
|
|
|
src_p.family = AF_INET6;
|
|
|
|
src_p.prefixlen = stream_getc (s);
|
|
|
|
stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen));
|
|
|
|
src_pp = &src_p;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
src_pp = NULL;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* 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)
|
|
|
|
{
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IPV6:
|
2002-12-13 21:15:29 +01:00
|
|
|
stream_get (&nexthop, s, 16);
|
2017-02-02 18:58:33 +01:00
|
|
|
/* For labeled-unicast, each nexthop is followed by label, but
|
|
|
|
* we don't care for delete.
|
|
|
|
*/
|
|
|
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_LABEL))
|
|
|
|
stream_forward_getp (s, sizeof(u_int32_t));
|
2016-08-24 07:39:08 +02:00
|
|
|
pnexthop = (union g_addr *)&nexthop;
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2016-09-02 16:32:14 +02:00
|
|
|
case NEXTHOP_TYPE_IFINDEX:
|
2002-12-13 21:15:29 +01:00
|
|
|
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))
|
2016-10-01 20:42:34 +02:00
|
|
|
api.tag = stream_getl (s);
|
2015-05-20 02:46:33 +02:00
|
|
|
else
|
|
|
|
api.tag = 0;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
|
2016-10-30 22:50:26 +01:00
|
|
|
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
|
2014-04-24 17:41:43 +02:00
|
|
|
api.flags, &p, src_pp, NULL, ifindex, client->rtm_table);
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2016-10-30 22:50:26 +01:00
|
|
|
rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance,
|
2014-04-24 17:41:43 +02:00
|
|
|
api.flags, &p, src_pp, pnexthop, ifindex, client->rtm_table);
|
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
|
|
|
}
|
|
|
|
|
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-10-30 22:50:26 +01:00
|
|
|
vrf_bitmap_set (client->ridinfo, zvrf_id (zvrf));
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2016-10-30 22:50:26 +01:00
|
|
|
router_id_get (&p, zvrf_id (zvrf));
|
2004-10-03 20:18:34 +02:00
|
|
|
|
2016-10-30 22:50:26 +01:00
|
|
|
return zsend_router_id_update (client, &p, zvrf_id (zvrf));
|
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-10-30 22:50:26 +01:00
|
|
|
vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf));
|
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-10-30 22:50:26 +01:00
|
|
|
vrf_bitmap_unset (client->redist[afi][i], zvrf_id (zvrf));
|
|
|
|
vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf));
|
|
|
|
vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf));
|
|
|
|
vrf_bitmap_unset (client->ridinfo, zvrf_id (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
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-06-01 19:19:30 +02:00
|
|
|
static void
|
|
|
|
zread_mpls_labels (int command, struct zserv *client, u_short length,
|
|
|
|
vrf_id_t vrf_id)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
enum lsp_types_t type;
|
|
|
|
struct prefix prefix;
|
|
|
|
enum nexthop_types_t gtype;
|
|
|
|
union g_addr gate;
|
2016-12-12 21:28:31 +01:00
|
|
|
ifindex_t ifindex;
|
2016-06-01 19:19:30 +02:00
|
|
|
mpls_label_t in_label, out_label;
|
|
|
|
u_int8_t distance;
|
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
|
|
|
zvrf = vrf_info_lookup (vrf_id);
|
|
|
|
if (!zvrf)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Get input stream. */
|
|
|
|
s = client->ibuf;
|
|
|
|
|
|
|
|
/* Get data. */
|
|
|
|
type = stream_getc (s);
|
|
|
|
prefix.family = stream_getl (s);
|
|
|
|
switch (prefix.family)
|
|
|
|
{
|
|
|
|
case AF_INET:
|
|
|
|
prefix.u.prefix4.s_addr = stream_get_ipv4 (s);
|
|
|
|
prefix.prefixlen = stream_getc (s);
|
|
|
|
gate.ipv4.s_addr = stream_get_ipv4 (s);
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
stream_get (&prefix.u.prefix6, s, 16);
|
|
|
|
prefix.prefixlen = stream_getc (s);
|
|
|
|
stream_get (&gate.ipv6, s, 16);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2016-12-12 21:28:31 +01:00
|
|
|
ifindex = stream_getl (s);
|
2016-06-01 19:19:30 +02:00
|
|
|
distance = stream_getc (s);
|
|
|
|
in_label = stream_getl (s);
|
|
|
|
out_label = stream_getl (s);
|
|
|
|
|
2016-12-12 21:28:31 +01:00
|
|
|
switch (prefix.family)
|
|
|
|
{
|
|
|
|
case AF_INET:
|
|
|
|
if (ifindex)
|
|
|
|
gtype = NEXTHOP_TYPE_IPV4_IFINDEX;
|
|
|
|
else
|
|
|
|
gtype = NEXTHOP_TYPE_IPV4;
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
if (ifindex)
|
|
|
|
gtype = NEXTHOP_TYPE_IPV6_IFINDEX;
|
|
|
|
else
|
|
|
|
gtype = NEXTHOP_TYPE_IPV6;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-09-22 04:59:57 +02:00
|
|
|
if (! mpls_enabled)
|
|
|
|
return;
|
|
|
|
|
2016-06-01 19:19:30 +02:00
|
|
|
if (command == ZEBRA_MPLS_LABELS_ADD)
|
|
|
|
{
|
|
|
|
mpls_lsp_install (zvrf, type, in_label, out_label, gtype, &gate,
|
2017-02-02 18:58:33 +01:00
|
|
|
ifindex);
|
2016-06-01 19:19:30 +02:00
|
|
|
if (out_label != MPLS_IMP_NULL_LABEL)
|
2016-12-12 21:28:31 +01:00
|
|
|
mpls_ftn_update (1, zvrf, type, &prefix, gtype, &gate, ifindex,
|
|
|
|
distance, out_label);
|
2016-06-01 19:19:30 +02:00
|
|
|
}
|
|
|
|
else if (command == ZEBRA_MPLS_LABELS_DELETE)
|
|
|
|
{
|
2017-02-02 18:58:33 +01:00
|
|
|
mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, ifindex);
|
2016-06-01 19:19:30 +02:00
|
|
|
if (out_label != MPLS_IMP_NULL_LABEL)
|
2016-12-12 21:28:31 +01:00
|
|
|
mpls_ftn_update (0, zvrf, type, &prefix, gtype, &gate, ifindex,
|
|
|
|
distance, out_label);
|
2016-06-01 19:19:30 +02:00
|
|
|
}
|
|
|
|
}
|
2017-03-20 15:34:49 +01:00
|
|
|
/* Send response to a label manager connect request to client */
|
|
|
|
static int
|
|
|
|
zsend_label_manager_connect_response (struct zserv *client, vrf_id_t vrf_id, u_short result)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
|
|
|
|
s = client->obuf;
|
|
|
|
stream_reset (s);
|
|
|
|
|
|
|
|
zserv_create_header (s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id);
|
|
|
|
|
|
|
|
/* result */
|
|
|
|
stream_putc (s, result);
|
|
|
|
|
|
|
|
/* Write packet size. */
|
|
|
|
stream_putw_at (s, 0, stream_get_endp (s));
|
|
|
|
|
|
|
|
return writen (client->sock, s->data, stream_get_endp (s));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
zread_label_manager_connect (struct zserv *client, vrf_id_t vrf_id)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
/* type of protocol (lib/zebra.h) */
|
|
|
|
u_char proto;
|
|
|
|
u_short instance;
|
|
|
|
|
|
|
|
/* Get input stream. */
|
|
|
|
s = client->ibuf;
|
|
|
|
|
|
|
|
/* Get data. */
|
|
|
|
proto = stream_getc (s);
|
|
|
|
instance = stream_getw (s);
|
|
|
|
|
|
|
|
/* accept only dynamic routing protocols */
|
|
|
|
if ((proto >= ZEBRA_ROUTE_MAX)
|
|
|
|
|| (proto <= ZEBRA_ROUTE_STATIC))
|
|
|
|
{
|
|
|
|
zlog_err ("client %d has wrong protocol %s",
|
|
|
|
client->sock, zebra_route_string(proto));
|
|
|
|
zsend_label_manager_connect_response (client, vrf_id, 1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
zlog_notice ("client %d with instance %u connected as %s",
|
|
|
|
client->sock, instance, zebra_route_string(proto));
|
|
|
|
client->proto = proto;
|
|
|
|
client->instance = instance;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Release previous labels of same protocol and instance.
|
|
|
|
This is done in case it restarted from an unexpected shutdown.
|
|
|
|
*/
|
|
|
|
release_daemon_chunks (proto, instance);
|
|
|
|
|
|
|
|
zlog_debug (" Label Manager client connected: sock %d, proto %s, instance %u",
|
|
|
|
client->sock, zebra_route_string(proto), instance);
|
|
|
|
/* send response back */
|
|
|
|
zsend_label_manager_connect_response (client, vrf_id, 0);
|
|
|
|
}
|
|
|
|
/* Send response to a get label chunk request to client */
|
|
|
|
static int
|
|
|
|
zsend_assign_label_chunk_response (struct zserv *client, vrf_id_t vrf_id,
|
|
|
|
struct label_manager_chunk *lmc)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
|
|
|
|
s = client->obuf;
|
|
|
|
stream_reset (s);
|
|
|
|
|
|
|
|
zserv_create_header (s, ZEBRA_GET_LABEL_CHUNK, vrf_id);
|
|
|
|
|
|
|
|
if (lmc)
|
|
|
|
{
|
|
|
|
/* keep */
|
|
|
|
stream_putc (s, lmc->keep);
|
|
|
|
/* start and end labels */
|
|
|
|
stream_putl (s, lmc->start);
|
|
|
|
stream_putl (s, lmc->end);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write packet size. */
|
|
|
|
stream_putw_at (s, 0, stream_get_endp (s));
|
|
|
|
|
|
|
|
return writen (client->sock, s->data, stream_get_endp (s));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
zread_get_label_chunk (struct zserv *client, vrf_id_t vrf_id)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
u_char keep;
|
|
|
|
uint32_t size;
|
|
|
|
struct label_manager_chunk *lmc;
|
|
|
|
|
|
|
|
/* Get input stream. */
|
|
|
|
s = client->ibuf;
|
|
|
|
|
|
|
|
/* Get data. */
|
|
|
|
keep = stream_getc (s);
|
|
|
|
size = stream_getl (s);
|
|
|
|
|
|
|
|
lmc = assign_label_chunk (client->proto, client->instance, keep, size);
|
|
|
|
if (!lmc)
|
|
|
|
zlog_err ("%s: Unable to assign Label Chunk of size %u", __func__, size);
|
|
|
|
else
|
|
|
|
zlog_debug ("Assigned Label Chunk %u - %u to %u",
|
|
|
|
lmc->start, lmc->end, keep);
|
|
|
|
/* send response back */
|
|
|
|
zsend_assign_label_chunk_response (client, vrf_id, lmc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
zread_release_label_chunk (struct zserv *client)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
uint32_t start, end;
|
|
|
|
|
|
|
|
/* Get input stream. */
|
|
|
|
s = client->ibuf;
|
|
|
|
|
|
|
|
/* Get data. */
|
|
|
|
start = stream_getl (s);
|
|
|
|
end = stream_getl (s);
|
|
|
|
|
|
|
|
release_label_chunk (client->proto, client->instance, start, end);
|
|
|
|
}
|
|
|
|
static void
|
|
|
|
zread_label_manager_request (int cmd, struct zserv *client, vrf_id_t vrf_id)
|
|
|
|
{
|
|
|
|
/* to avoid sending other messages like ZERBA_INTERFACE_UP */
|
|
|
|
if (cmd == ZEBRA_LABEL_MANAGER_CONNECT)
|
|
|
|
client->is_synchronous = 1;
|
|
|
|
|
|
|
|
/* external label manager */
|
|
|
|
if (lm_is_external)
|
2017-04-26 11:50:21 +02:00
|
|
|
zread_relay_label_manager_request (cmd, client, vrf_id);
|
2017-03-20 15:34:49 +01:00
|
|
|
/* this is a label manager */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (cmd == ZEBRA_LABEL_MANAGER_CONNECT)
|
|
|
|
zread_label_manager_connect (client, vrf_id);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Sanity: don't allow 'unidentified' requests */
|
|
|
|
if (!client->proto)
|
|
|
|
{
|
|
|
|
zlog_err ("Got label request from an unidentified client");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (cmd == ZEBRA_GET_LABEL_CHUNK)
|
|
|
|
zread_get_label_chunk (client, vrf_id);
|
|
|
|
else if (cmd == ZEBRA_RELEASE_LABEL_CHUNK)
|
|
|
|
zread_release_label_chunk (client);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-06-01 19:19:30 +02:00
|
|
|
|
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)
|
|
|
|
{
|
2016-10-29 18:37:11 +02:00
|
|
|
struct vrf *vrf;
|
2016-03-02 02:08:43 +01:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
|
2016-10-29 18:37:11 +02:00
|
|
|
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
|
2016-03-02 02:08:43 +01:00
|
|
|
{
|
2016-10-29 18:37:11 +02:00
|
|
|
if ((zvrf = vrf->info) != NULL)
|
2016-03-02 02:08:43 +01:00
|
|
|
{
|
2016-10-30 22:50:26 +01:00
|
|
|
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_NEXTHOP_TYPE);
|
|
|
|
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_NEXTHOP_TYPE);
|
|
|
|
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_IMPORT_CHECK_TYPE);
|
|
|
|
zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_IMPORT_CHECK_TYPE);
|
2016-06-01 19:19:30 +02:00
|
|
|
if (client->proto == ZEBRA_ROUTE_LDP)
|
|
|
|
{
|
|
|
|
hash_iterate(zvrf->lsp_table, mpls_ldp_lsp_uninstall_all,
|
|
|
|
zvrf->lsp_table);
|
|
|
|
mpls_ldp_ftn_uninstall_all (zvrf, AFI_IP);
|
|
|
|
mpls_ldp_ftn_uninstall_all (zvrf, AFI_IP6);
|
|
|
|
}
|
2016-03-02 02:08:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2017-03-20 15:34:49 +01:00
|
|
|
/* Release Label Manager chunks */
|
|
|
|
release_daemon_chunks (client->proto, client->instance);
|
|
|
|
|
2017-02-01 19:10:56 +01:00
|
|
|
/* Cleanup any FECs registered by this client. */
|
|
|
|
zebra_mpls_cleanup_fecs_for_client (vrf_info_lookup(VRF_DEFAULT), client);
|
|
|
|
|
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
|
|
|
|
2017-06-06 18:19:17 +02:00
|
|
|
/* Free bitmaps. */
|
|
|
|
for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++)
|
|
|
|
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
|
|
|
vrf_bitmap_free (client->redist[afi][i]);
|
|
|
|
|
|
|
|
vrf_bitmap_free (client->redist_default);
|
|
|
|
vrf_bitmap_free (client->ifinfo);
|
|
|
|
vrf_bitmap_free (client->ridinfo);
|
|
|
|
|
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
|
|
|
|
2017-01-18 01:30:43 +01:00
|
|
|
client->connect_time = monotime(NULL);
|
*: add VRF ID in the API message header
The API messages are used by zebra to exchange the interfaces, addresses,
routes and router-id information with its clients. To distinguish which
VRF the information belongs to, a new field "VRF ID" is added in the
message header. And hence the message version is increased to 3.
* The new field "VRF ID" in the message header:
Length (2 bytes)
Marker (1 byte)
Version (1 byte)
VRF ID (2 bytes, newly added)
Command (2 bytes)
- Client side:
- zclient_create_header() adds the VRF ID in the message header.
- zclient_read() extracts and validates the VRF ID from the header,
and passes the VRF ID to the callback functions registered to
the API messages.
- All relative functions are appended with a new parameter "vrf_id",
including all the callback functions.
- "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6".
Clients need to correctly set the VRF ID when using the API
functions zapi_ipv4_route() and zapi_ipv6_route().
- Till now all messages sent from a client have the default VRF ID
"0" in the header.
- The HELLO message is special, which is used as the heart-beat of
a client, and has no relation with VRF. The VRF ID in the HELLO
message header will always be 0 and ignored by zebra.
- Zebra side:
- zserv_create_header() adds the VRF ID in the message header.
- zebra_client_read() extracts and validates the VRF ID from the
header, and passes the VRF ID to the functions which process
the received messages.
- All relative functions are appended with a new parameter "vrf_id".
* Suppress the messages in a VRF which a client does not care:
Some clients may not care about the information in the VRF X, and
zebra should not send the messages in the VRF X to those clients.
Extra flags are used to indicate which VRF is registered by a client,
and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client
can unregister a VRF when it does not need any information in that
VRF.
A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF
will automatically register to that VRF.
- lib/vrf:
A new utility "VRF bit-map" is provided to manage the flags for
VRFs, one bit per VRF ID.
- Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a
bit-map;
- Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag
in the given bit-map, corresponding to the given VRF ID;
- Use vrf_bitmap_check() to test whether the flag, in the given
bit-map and for the given VRF ID, is set.
- Client side:
- In "struct zclient", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
default_information
These flags are extended for each VRF, and controlled by the
clients themselves (or with the help of zclient_redistribute()
and zclient_redistribute_default()).
- Zebra side:
- In "struct zserv", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
redist_default
ifinfo
ridinfo
These flags are extended for each VRF, as the VRF registration
flags. They are maintained on receiving a ZEBRA_XXX_ADD or
ZEBRA_XXX_DELETE message.
When sending an interface/address/route/router-id message in
a VRF to a client, if the corresponding VRF registration flag
is not set, this message will not be dropped by zebra.
- A new function zread_vrf_unregister() is introduced to process
the new command ZEBRA_VRF_UNREGISTER. All the VRF registration
flags are cleared for the requested VRF.
Those clients, who support only the default VRF, will never receive
a message in a non-default VRF, thanks to the filter in zebra.
* New callback for the event of successful connection to zebra:
- zclient_start() is splitted, keeping only the code of connecting
to zebra.
- Now zclient_init()=>zclient_connect()=>zclient_start() operations
are purely dealing with the connection to zbera.
- Once zebra is successfully connected, at the end of zclient_start(),
a new callback is used to inform the client about connection.
- Till now, in the callback of connect-to-zebra event, all clients
send messages to zebra to request the router-id/interface/routes
information in the default VRF.
Of corse in future the client can do anything it wants in this
callback. For example, it may send requests for both default VRF
and some non-default VRFs.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
Conflicts:
lib/zclient.h
lib/zebra.h
zebra/zserv.c
zebra/zserv.h
Conflicts:
bgpd/bgp_nexthop.c
bgpd/bgp_nht.c
bgpd/bgp_zebra.c
isisd/isis_zebra.c
lib/zclient.c
lib/zclient.h
lib/zebra.h
nhrpd/nhrp_interface.c
nhrpd/nhrp_route.c
nhrpd/nhrpd.h
ospf6d/ospf6_zebra.c
ospf6d/ospf6_zebra.h
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
pimd/pim_zebra.c
pimd/pim_zlookup.c
ripd/rip_zebra.c
ripngd/ripng_zebra.c
zebra/redistribute.c
zebra/rt_netlink.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h
zebra/zserv.c
zebra/zserv.h
2014-10-16 03:52:36 +02:00
|
|
|
/* Initialize flags */
|
|
|
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
|
|
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
|
|
|
client->redist[afi][i] = vrf_bitmap_init ();
|
|
|
|
client->redist_default = vrf_bitmap_init ();
|
|
|
|
client->ifinfo = vrf_bitmap_init ();
|
|
|
|
client->ridinfo = vrf_bitmap_init ();
|
2015-05-20 02:47:22 +02:00
|
|
|
|
2017-03-20 15:34:49 +01:00
|
|
|
/* by default, it's not a synchronous client */
|
|
|
|
client->is_synchronous = 0;
|
|
|
|
|
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
|
|
|
|
2017-01-18 01:30:43 +01:00
|
|
|
client->last_read_time = monotime(NULL);
|
2015-05-20 02:47:22 +02:00
|
|
|
client->last_read_cmd = command;
|
|
|
|
|
2016-11-02 15:16:58 +01:00
|
|
|
zvrf = zebra_vrf_lookup_by_id (vrf_id);
|
2016-04-20 22:12:29 +02:00
|
|
|
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;
|
bgpd: add L3/L2VPN Virtual Network Control feature
This feature adds an L3 & L2 VPN application that makes use of the VPN
and Encap SAFIs. This code is currently used to support IETF NVO3 style
operation. In NVO3 terminology it provides the Network Virtualization
Authority (NVA) and the ability to import/export IP prefixes and MAC
addresses from Network Virtualization Edges (NVEs). The code supports
per-NVE tables.
The NVE-NVA protocol used to communicate routing and Ethernet / Layer 2
(L2) forwarding information between NVAs and NVEs is referred to as the
Remote Forwarder Protocol (RFP). OpenFlow is an example RFP. For
general background on NVO3 and RFP concepts see [1]. For information on
Openflow see [2].
RFPs are integrated with BGP via the RF API contained in the new "rfapi"
BGP sub-directory. Currently, only a simple example RFP is included in
Quagga. Developers may use this example as a starting point to integrate
Quagga with an RFP of their choosing, e.g., OpenFlow. The RFAPI code
also supports the ability import/export of routing information between
VNC and customer edge routers (CEs) operating within a virtual
network. Import/export may take place between BGP views or to the
default zebera VRF.
BGP, with IP VPNs and Tunnel Encapsulation, is used to distribute VPN
information between NVAs. BGP based IP VPN support is defined in
RFC4364, BGP/MPLS IP Virtual Private Networks (VPNs), and RFC4659,
BGP-MPLS IP Virtual Private Network (VPN) Extension for IPv6 VPN . Use
of both the Encapsulation Subsequent Address Family Identifier (SAFI)
and the Tunnel Encapsulation Attribute, RFC5512, The BGP Encapsulation
Subsequent Address Family Identifier (SAFI) and the BGP Tunnel
Encapsulation Attribute, are supported. MAC address distribution does
not follow any standard BGB encoding, although it was inspired by the
early IETF EVPN concepts.
The feature is conditionally compiled and disabled by default.
Use the --enable-bgp-vnc configure option to enable.
The majority of this code was authored by G. Paul Ziemba
<paulz@labn.net>.
[1] http://tools.ietf.org/html/draft-ietf-nvo3-nve-nva-cp-req
[2] https://www.opennetworking.org/sdn-resources/technical-library
Now includes changes needed to merge with cmaster-next.
2016-05-07 20:18:56 +02:00
|
|
|
case ZEBRA_IPV4_NEXTHOP_ADD:
|
|
|
|
zread_ipv4_add(client, length, zvrf); /* LB: r1.0 merge - id was 1 */
|
|
|
|
break;
|
|
|
|
case ZEBRA_IPV4_NEXTHOP_DELETE:
|
|
|
|
zread_ipv4_delete(client, length, zvrf); /* LB: r1.0 merge - id was 1 */
|
|
|
|
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;
|
2014-07-01 20:15:52 +02:00
|
|
|
case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB:
|
|
|
|
zread_ipv4_nexthop_lookup_mrib (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:
|
2017-06-08 13:55:25 +02:00
|
|
|
#if defined (HAVE_RTADV)
|
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
|
|
|
zebra_interface_radv_set (client, sock, length, zvrf, 1);
|
2017-06-08 13:55:25 +02:00
|
|
|
#endif
|
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
|
|
|
break;
|
|
|
|
case ZEBRA_INTERFACE_DISABLE_RADV:
|
2017-06-08 13:55:25 +02:00
|
|
|
#if defined (HAVE_RTADV)
|
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
|
|
|
zebra_interface_radv_set (client, sock, length, zvrf, 0);
|
2017-06-08 13:55:25 +02:00
|
|
|
#endif
|
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
|
|
|
break;
|
2016-06-01 19:19:30 +02:00
|
|
|
case ZEBRA_MPLS_LABELS_ADD:
|
|
|
|
case ZEBRA_MPLS_LABELS_DELETE:
|
|
|
|
zread_mpls_labels (command, client, length, vrf_id);
|
|
|
|
break;
|
2016-08-11 02:04:20 +02:00
|
|
|
case ZEBRA_IPMR_ROUTE_STATS:
|
|
|
|
zebra_ipmr_route_stats (client, sock, length, zvrf);
|
|
|
|
break;
|
2017-03-20 15:34:49 +01:00
|
|
|
case ZEBRA_LABEL_MANAGER_CONNECT:
|
|
|
|
case ZEBRA_GET_LABEL_CHUNK:
|
|
|
|
case ZEBRA_RELEASE_LABEL_CHUNK:
|
|
|
|
zread_label_manager_request (command, client, vrf_id);
|
|
|
|
break;
|
2017-02-01 19:10:56 +01:00
|
|
|
case ZEBRA_FEC_REGISTER:
|
|
|
|
zserv_fec_register (client, sock, length);
|
|
|
|
break;
|
|
|
|
case ZEBRA_FEC_UNREGISTER:
|
|
|
|
zserv_fec_unregister (client, sock, length);
|
|
|
|
break;
|
2017-05-15 07:38:26 +02:00
|
|
|
case ZEBRA_ADVERTISE_ALL_VNI:
|
|
|
|
zebra_vxlan_advertise_all_vni (client, sock, length, zvrf);
|
|
|
|
break;
|
|
|
|
case ZEBRA_REMOTE_VTEP_ADD:
|
|
|
|
zebra_vxlan_remote_vtep_add (client, sock, length, zvrf);
|
|
|
|
break;
|
|
|
|
case ZEBRA_REMOTE_VTEP_DEL:
|
|
|
|
zebra_vxlan_remote_vtep_del (client, sock, length, zvrf);
|
|
|
|
break;
|
2017-05-15 07:44:13 +02:00
|
|
|
case ZEBRA_REMOTE_MACIP_ADD:
|
|
|
|
zebra_vxlan_remote_macip_add (client, sock, length, zvrf);
|
|
|
|
break;
|
|
|
|
case ZEBRA_REMOTE_MACIP_DEL:
|
|
|
|
zebra_vxlan_remote_macip_del (client, sock, length, zvrf);
|
|
|
|
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) )
|
*: get rid of zlog(*, LOG_LEVEL, ...)
Result of running the following Coccinelle patch + fixups:
<<EOF
/* long-forms: zlog(NULL, <level>, ...)
* => zlog_level(...)
*/
@@
expression list args;
@@
- zlog(NULL, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression list args;
@@
- zlog(NULL, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression list args;
@@
- zlog(NULL, LOG_INFO, args)
+ zlog_info(args)
@@
expression list args;
@@
- zlog(NULL, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression list args;
@@
- zlog(NULL, LOG_ERR, args)
+ zlog_err(args)
/* long-forms: zlog(base->log, <level>, ...)
* => zlog_level(...)
*/
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_INFO, args)
+ zlog_info(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_ERR, args)
+ zlog_err(args)
EOF
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2016-11-13 04:19:14 +01:00
|
|
|
zlog_err("Can't raise privileges");
|
2003-06-04 15:59:38 +02:00
|
|
|
|
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) )
|
*: get rid of zlog(*, LOG_LEVEL, ...)
Result of running the following Coccinelle patch + fixups:
<<EOF
/* long-forms: zlog(NULL, <level>, ...)
* => zlog_level(...)
*/
@@
expression list args;
@@
- zlog(NULL, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression list args;
@@
- zlog(NULL, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression list args;
@@
- zlog(NULL, LOG_INFO, args)
+ zlog_info(args)
@@
expression list args;
@@
- zlog(NULL, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression list args;
@@
- zlog(NULL, LOG_ERR, args)
+ zlog_err(args)
/* long-forms: zlog(base->log, <level>, ...)
* => zlog_level(...)
*/
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_DEBUG, args)
+ zlog_debug(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_NOTICE, args)
+ zlog_notice(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_INFO, args)
+ zlog_info(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_WARNING, args)
+ zlog_warn(args)
@@
expression base;
expression list args;
@@
- zlog(base->log, LOG_ERR, args)
+ zlog_err(args)
EOF
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2016-11-13 04:19:14 +01:00
|
|
|
zlog_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:
|
2017-04-25 00:33:25 +02:00
|
|
|
thread_add_read(zebrad.master, zebra_accept, client, sock, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case ZEBRA_READ:
|
2017-05-05 23:22:25 +02:00
|
|
|
client->t_read = NULL;
|
|
|
|
thread_add_read(zebrad.master, zebra_client_read, client, sock,
|
|
|
|
&client->t_read);
|
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);
|
|
|
|
}
|
|
|
|
|
2017-01-18 01:30:43 +01:00
|
|
|
now = monotime(NULL);
|
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);
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out (vty, "\n");
|
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
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "------------------------ \n");
|
|
|
|
vty_out (vty, "FD: %d \n", client->sock);
|
|
|
|
vty_out (vty, "Route Table ID: %d \n", client->rtm_table);
|
2015-05-20 02:47:22 +02:00
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Connect Time: %s \n",
|
2017-06-21 05:10:57 +02:00
|
|
|
zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF));
|
2015-05-20 02:47:22 +02:00
|
|
|
if (client->nh_reg_time)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Nexthop Registry Time: %s \n",
|
2017-06-21 05:10:57 +02:00
|
|
|
zserv_time_buf(&client->nh_reg_time, nhbuf, ZEBRA_TIME_BUF));
|
2015-05-20 02:47:22 +02:00
|
|
|
if (client->nh_last_upd_time)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Nexthop Last Update Time: %s \n",
|
2017-06-21 05:10:57 +02:00
|
|
|
zserv_time_buf(&client->nh_last_upd_time, mbuf, ZEBRA_TIME_BUF));
|
|
|
|
else
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "No Nexthop Update sent\n");
|
2015-05-20 02:47:22 +02:00
|
|
|
}
|
|
|
|
else
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Not registered for Nexthop Updates\n");
|
2015-05-20 02:47:22 +02:00
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Last Msg Rx Time: %s \n",
|
2017-06-21 05:10:57 +02:00
|
|
|
zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF));
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Last Msg Tx Time: %s \n",
|
2017-06-21 05:10:57 +02:00
|
|
|
zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF));
|
2015-05-20 02:47:22 +02:00
|
|
|
if (client->last_read_time)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Last Rcvd Cmd: %s \n",
|
2017-06-21 05:10:57 +02:00
|
|
|
zserv_command_string(client->last_read_cmd));
|
2015-05-20 02:47:22 +02:00
|
|
|
if (client->last_write_time)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Last Sent Cmd: %s \n",
|
2017-06-21 05:10:57 +02:00
|
|
|
zserv_command_string(client->last_write_cmd));
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out (vty, "\n");
|
2017-06-21 05:10:57 +02:00
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Type Add Update Del \n");
|
|
|
|
vty_out (vty, "================================================== \n");
|
|
|
|
vty_out (vty, "IPv4 %-12d%-12d%-12d\n", client->v4_route_add_cnt,
|
2017-06-21 05:10:57 +02:00
|
|
|
client->v4_route_upd8_cnt, client->v4_route_del_cnt);
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "IPv6 %-12d%-12d%-12d\n", client->v6_route_add_cnt,
|
2017-06-21 05:10:57 +02:00
|
|
|
client->v6_route_upd8_cnt, client->v6_route_del_cnt);
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Redist:v4 %-12d%-12d%-12d\n", client->redist_v4_add_cnt, 0,
|
2017-06-21 05:10:57 +02:00
|
|
|
client->redist_v4_del_cnt);
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Redist:v6 %-12d%-12d%-12d\n", client->redist_v6_add_cnt, 0,
|
2017-06-21 05:10:57 +02:00
|
|
|
client->redist_v6_del_cnt);
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Connected %-12d%-12d%-12d\n", client->ifadd_cnt, 0,
|
2017-06-21 05:10:57 +02:00
|
|
|
client->ifdel_cnt);
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "BFD peer %-12d%-12d%-12d\n", client->bfd_peer_add_cnt,
|
2017-06-21 05:10:57 +02:00
|
|
|
client->bfd_peer_upd8_cnt, client->bfd_peer_del_cnt);
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Interface Up Notifications: %d\n",client->ifup_cnt);
|
|
|
|
vty_out (vty, "Interface Down Notifications: %d\n",client->ifdown_cnt);
|
2017-07-14 14:24:46 +02:00
|
|
|
vty_out (vty, "VNI add notifications: %d\n", client->vniadd_cnt);
|
|
|
|
vty_out (vty, "VNI delete notifications: %d\n", client->vnidel_cnt);
|
|
|
|
vty_out (vty, "MAC-IP add notifications: %d\n", client->macipadd_cnt);
|
|
|
|
vty_out (vty, "MAC-IP delete notifications: %d\n", client->macipdel_cnt);
|
2017-06-21 05:10:57 +02:00
|
|
|
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out (vty, "\n");
|
2015-05-20 02:47:22 +02:00
|
|
|
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];
|
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d\n",
|
2015-05-20 02:47:22 +02:00
|
|
|
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,
|
2017-06-21 05:10:57 +02:00
|
|
|
client->v6_route_del_cnt);
|
2015-05-20 02:47:22 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-07-21 17:50:17 +02:00
|
|
|
struct zserv *
|
|
|
|
zebra_find_client (u_char proto)
|
|
|
|
{
|
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct zserv *client;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
|
|
|
{
|
|
|
|
if (client->proto == proto)
|
|
|
|
return client;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-01-18 16:17:20 +01:00
|
|
|
#ifdef HAVE_NETLINK
|
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")
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "table %d\n",zebrad.rtm_table_default);
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-09-23 15:47:20 +02:00
|
|
|
DEFUN (config_table,
|
2002-12-13 21:15:29 +01:00
|
|
|
config_table_cmd,
|
|
|
|
"table TABLENO",
|
|
|
|
"Configure target kernel routing table\n"
|
|
|
|
"TABLE integer\n")
|
|
|
|
{
|
2016-09-24 23:58:50 +02:00
|
|
|
zebrad.rtm_table_default = strtol (argv[1]->arg, (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,
|
2016-09-24 23:58:50 +02:00
|
|
|
"no table [TABLENO]",
|
2015-11-23 19:05:03 +01:00
|
|
|
NO_STR
|
|
|
|
"Configure target kernel routing table\n"
|
|
|
|
"TABLE integer\n")
|
|
|
|
{
|
|
|
|
zebrad.rtm_table_default = 0;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2017-01-18 16:17:20 +01:00
|
|
|
#endif
|
2015-11-23 19:05:03 +01:00
|
|
|
|
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)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Can't turn on IP forwarding\n");
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2003-05-25 13:43:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Can't turn off IP forwarding\n");
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-05-18 19:13:32 +02:00
|
|
|
DEFUN (show_zebra,
|
|
|
|
show_zebra_cmd,
|
|
|
|
"show zebra",
|
|
|
|
SHOW_STR
|
|
|
|
"Zebra information\n")
|
|
|
|
{
|
|
|
|
struct vrf *vrf;
|
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty,
|
|
|
|
" Route Route Neighbor LSP LSP\n");
|
|
|
|
vty_out (vty,
|
|
|
|
"VRF Installs Removals Updates Installs Removals\n");
|
2017-05-18 19:13:32 +02:00
|
|
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
|
|
|
{
|
|
|
|
struct zebra_vrf *zvrf = vrf->info;
|
2017-07-13 18:50:29 +02:00
|
|
|
vty_out (vty,"%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n",
|
2017-05-18 19:13:32 +02:00
|
|
|
vrf->name, zvrf->installs, zvrf->removals,
|
2017-06-21 05:10:57 +02:00
|
|
|
zvrf->neigh_updates, zvrf->lsp_installs,zvrf->lsp_removals);
|
2017-05-18 19:13:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* This command is for debugging purpose. */
|
|
|
|
DEFUN (show_zebra_client,
|
|
|
|
show_zebra_client_cmd,
|
|
|
|
"show zebra client",
|
|
|
|
SHOW_STR
|
2016-10-06 01:02:57 +02:00
|
|
|
"Zebra information\n"
|
2017-01-30 01:07:04 +01:00
|
|
|
"Client information\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
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
|
2017-01-30 01:07:04 +01:00
|
|
|
"Zebra information brief\n"
|
|
|
|
"Client information brief\n"
|
|
|
|
"Brief Summary\n")
|
2015-05-20 02:47:22 +02:00
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
struct zserv *client;
|
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty,
|
|
|
|
"Name Connect Time Last Read Last Write IPv4 Routes IPv6 Routes \n");
|
|
|
|
vty_out (vty,
|
|
|
|
"--------------------------------------------------------------------------------\n");
|
2015-05-20 02:47:22 +02:00
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
|
|
|
zebra_show_client_brief(vty, client);
|
2015-05-20 02:40:34 +02:00
|
|
|
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Routes column shows (added+updated)/deleted\n");
|
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)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "table %d\n",zebrad.rtm_table_default);
|
2002-12-13 21:15:29 +01:00
|
|
|
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)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "IP forwarding is off\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "IP forwarding is on\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "ipv6 forwarding is unknown\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case 0:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "ipv6 forwarding is %s\n", "off");
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "ipv6 forwarding is %s\n", "on");
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
default:
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "ipv6 forwarding is %s\n", "off");
|
2002-12-13 21:15:29 +01:00
|
|
|
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
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Can't turn on IPv6 forwarding\n");
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2004-02-11 23:42:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "Can't turn off IPv6 forwarding\n");
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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 ())
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "no ip forwarding\n");
|
2016-06-21 21:57:22 +02:00
|
|
|
if (!ipforward_ipv6 ())
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out (vty, "no ipv6 forwarding\n");
|
|
|
|
vty_out (vty, "!\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
|
|
|
/* 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);
|
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);
|
2017-05-18 19:13:32 +02:00
|
|
|
install_element (ENABLE_NODE, &show_zebra_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
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 (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 */
|
|
|
|
|
|
|
|
install_element (VIEW_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);
|
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 */
|
|
|
|
}
|