2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* IS-IS Rout(e)ing protocol - isis_zebra.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 2001,2002 Sampo Saaristo
|
|
|
|
* Tampere University of Technology
|
|
|
|
* Institute of Communications Engineering
|
2015-11-12 14:24:22 +01:00
|
|
|
* Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org>
|
2003-12-23 09:09:43 +01:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public Licenseas published by the Free
|
|
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
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
|
2003-12-23 09:09:43 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "thread.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "log.h"
|
2019-08-06 22:43:46 +02:00
|
|
|
#include "lib_errors.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
#include "if.h"
|
|
|
|
#include "network.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "zclient.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "linklist.h"
|
2015-11-12 14:24:22 +01:00
|
|
|
#include "nexthop.h"
|
*: 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
|
|
|
#include "vrf.h"
|
2017-09-12 04:05:16 +02:00
|
|
|
#include "libfrr.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
#include "isisd/isis_constants.h"
|
|
|
|
#include "isisd/isis_common.h"
|
2012-03-24 16:35:20 +01:00
|
|
|
#include "isisd/isis_flags.h"
|
|
|
|
#include "isisd/isis_misc.h"
|
|
|
|
#include "isisd/isis_circuit.h"
|
2005-09-04 23:36:36 +02:00
|
|
|
#include "isisd/isisd.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
#include "isisd/isis_circuit.h"
|
|
|
|
#include "isisd/isis_csm.h"
|
2012-03-24 16:35:20 +01:00
|
|
|
#include "isisd/isis_lsp.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
#include "isisd/isis_route.h"
|
|
|
|
#include "isisd/isis_zebra.h"
|
2020-05-04 18:26:21 +02:00
|
|
|
#include "isisd/isis_adjacency.h"
|
2016-04-19 19:03:05 +02:00
|
|
|
#include "isisd/isis_te.h"
|
2019-08-04 03:02:37 +02:00
|
|
|
#include "isisd/isis_sr.h"
|
2020-07-22 20:32:35 +02:00
|
|
|
#include "isisd/isis_ldp_sync.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2019-08-04 03:02:37 +02:00
|
|
|
struct zclient *zclient;
|
|
|
|
static struct zclient *zclient_sync;
|
|
|
|
|
2004-10-03 20:18:34 +02:00
|
|
|
/* Router-id update message from zebra. */
|
2019-05-03 21:42:59 +02:00
|
|
|
static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
|
2004-10-03 20:18:34 +02:00
|
|
|
{
|
2012-03-24 16:35:20 +01:00
|
|
|
struct isis_area *area;
|
|
|
|
struct listnode *node;
|
2004-10-03 20:18:34 +02:00
|
|
|
struct prefix router_id;
|
2020-07-13 14:37:59 +02:00
|
|
|
struct isis *isis = NULL;
|
|
|
|
|
|
|
|
isis = isis_lookup_by_vrfid(vrf_id);
|
|
|
|
|
|
|
|
if (isis == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
zebra_router_id_update_read(zclient->ibuf, &router_id);
|
|
|
|
if (isis->router_id == router_id.u.prefix4.s_addr)
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
isis->router_id = router_id.u.prefix4.s_addr;
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
|
|
|
|
if (listcount(area->area_addrs) > 0)
|
|
|
|
lsp_regenerate_schedule(area, area->is_type, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-10-03 20:18:34 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2019-05-03 21:42:59 +02:00
|
|
|
static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2020-10-08 19:05:08 +02:00
|
|
|
struct isis_circuit *circuit;
|
2003-12-23 09:09:43 +01:00
|
|
|
struct connected *c;
|
|
|
|
struct prefix *p;
|
2015-11-23 21:44:34 +01:00
|
|
|
char buf[PREFIX2STR_BUFFER];
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
|
*: add VRF ID in the API message header
The API messages are used by zebra to exchange the interfaces, addresses,
routes and router-id information with its clients. To distinguish which
VRF the information belongs to, a new field "VRF ID" is added in the
message header. And hence the message version is increased to 3.
* The new field "VRF ID" in the message header:
Length (2 bytes)
Marker (1 byte)
Version (1 byte)
VRF ID (2 bytes, newly added)
Command (2 bytes)
- Client side:
- zclient_create_header() adds the VRF ID in the message header.
- zclient_read() extracts and validates the VRF ID from the header,
and passes the VRF ID to the callback functions registered to
the API messages.
- All relative functions are appended with a new parameter "vrf_id",
including all the callback functions.
- "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6".
Clients need to correctly set the VRF ID when using the API
functions zapi_ipv4_route() and zapi_ipv6_route().
- Till now all messages sent from a client have the default VRF ID
"0" in the header.
- The HELLO message is special, which is used as the heart-beat of
a client, and has no relation with VRF. The VRF ID in the HELLO
message header will always be 0 and ignored by zebra.
- Zebra side:
- zserv_create_header() adds the VRF ID in the message header.
- zebra_client_read() extracts and validates the VRF ID from the
header, and passes the VRF ID to the functions which process
the received messages.
- All relative functions are appended with a new parameter "vrf_id".
* Suppress the messages in a VRF which a client does not care:
Some clients may not care about the information in the VRF X, and
zebra should not send the messages in the VRF X to those clients.
Extra flags are used to indicate which VRF is registered by a client,
and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client
can unregister a VRF when it does not need any information in that
VRF.
A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF
will automatically register to that VRF.
- lib/vrf:
A new utility "VRF bit-map" is provided to manage the flags for
VRFs, one bit per VRF ID.
- Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a
bit-map;
- Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag
in the given bit-map, corresponding to the given VRF ID;
- Use vrf_bitmap_check() to test whether the flag, in the given
bit-map and for the given VRF ID, is set.
- Client side:
- In "struct zclient", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
default_information
These flags are extended for each VRF, and controlled by the
clients themselves (or with the help of zclient_redistribute()
and zclient_redistribute_default()).
- Zebra side:
- In "struct zserv", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
redist_default
ifinfo
ridinfo
These flags are extended for each VRF, as the VRF registration
flags. They are maintained on receiving a ZEBRA_XXX_ADD or
ZEBRA_XXX_DELETE message.
When sending an interface/address/route/router-id message in
a VRF to a client, if the corresponding VRF registration flag
is not set, this message will not be dropped by zebra.
- A new function zread_vrf_unregister() is introduced to process
the new command ZEBRA_VRF_UNREGISTER. All the VRF registration
flags are cleared for the requested VRF.
Those clients, who support only the default VRF, will never receive
a message in a non-default VRF, thanks to the filter in zebra.
* New callback for the event of successful connection to zebra:
- zclient_start() is splitted, keeping only the code of connecting
to zebra.
- Now zclient_init()=>zclient_connect()=>zclient_start() operations
are purely dealing with the connection to zbera.
- Once zebra is successfully connected, at the end of zclient_start(),
a new callback is used to inform the client about connection.
- Till now, in the callback of connect-to-zebra event, all clients
send messages to zebra to request the router-id/interface/routes
information in the default VRF.
Of corse in future the client can do anything it wants in this
callback. For example, it may send requests for both default VRF
and some non-default VRFs.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
Conflicts:
lib/zclient.h
lib/zebra.h
zebra/zserv.c
zebra/zserv.h
Conflicts:
bgpd/bgp_nexthop.c
bgpd/bgp_nht.c
bgpd/bgp_zebra.c
isisd/isis_zebra.c
lib/zclient.c
lib/zclient.h
lib/zebra.h
nhrpd/nhrp_interface.c
nhrpd/nhrp_route.c
nhrpd/nhrpd.h
ospf6d/ospf6_zebra.c
ospf6d/ospf6_zebra.h
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
pimd/pim_zebra.c
pimd/pim_zlookup.c
ripd/rip_zebra.c
ripngd/ripng_zebra.c
zebra/redistribute.c
zebra/rt_netlink.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h
zebra/zserv.c
zebra/zserv.h
2014-10-16 03:52:36 +02:00
|
|
|
zclient->ibuf, vrf_id);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
if (c == NULL)
|
|
|
|
return 0;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
p = c->address;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2015-11-23 21:44:34 +01:00
|
|
|
prefix2str(p, buf, sizeof(buf));
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef EXTREME_DEBUG
|
2004-09-10 22:48:21 +02:00
|
|
|
if (p->family == AF_INET)
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug("connected IP address %s", buf);
|
2003-12-23 09:09:43 +01:00
|
|
|
if (p->family == AF_INET6)
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug("connected IPv6 address %s", buf);
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif /* EXTREME_DEBUG */
|
2020-10-08 19:05:08 +02:00
|
|
|
|
|
|
|
if (if_is_operative(c->ifp)) {
|
|
|
|
circuit = circuit_scan_by_ifp(c->ifp);
|
|
|
|
if (circuit)
|
|
|
|
isis_circuit_add_addr(circuit, c);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-05-03 21:42:59 +02:00
|
|
|
static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2020-10-08 19:05:08 +02:00
|
|
|
struct isis_circuit *circuit;
|
2003-12-23 09:09:43 +01:00
|
|
|
struct connected *c;
|
2004-10-07 22:07:40 +02:00
|
|
|
#ifdef EXTREME_DEBUG
|
2004-09-14 15:54:30 +02:00
|
|
|
struct prefix *p;
|
2015-11-23 21:44:34 +01:00
|
|
|
char buf[PREFIX2STR_BUFFER];
|
2004-10-07 22:07:40 +02:00
|
|
|
#endif /* EXTREME_DEBUG */
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
|
*: add VRF ID in the API message header
The API messages are used by zebra to exchange the interfaces, addresses,
routes and router-id information with its clients. To distinguish which
VRF the information belongs to, a new field "VRF ID" is added in the
message header. And hence the message version is increased to 3.
* The new field "VRF ID" in the message header:
Length (2 bytes)
Marker (1 byte)
Version (1 byte)
VRF ID (2 bytes, newly added)
Command (2 bytes)
- Client side:
- zclient_create_header() adds the VRF ID in the message header.
- zclient_read() extracts and validates the VRF ID from the header,
and passes the VRF ID to the callback functions registered to
the API messages.
- All relative functions are appended with a new parameter "vrf_id",
including all the callback functions.
- "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6".
Clients need to correctly set the VRF ID when using the API
functions zapi_ipv4_route() and zapi_ipv6_route().
- Till now all messages sent from a client have the default VRF ID
"0" in the header.
- The HELLO message is special, which is used as the heart-beat of
a client, and has no relation with VRF. The VRF ID in the HELLO
message header will always be 0 and ignored by zebra.
- Zebra side:
- zserv_create_header() adds the VRF ID in the message header.
- zebra_client_read() extracts and validates the VRF ID from the
header, and passes the VRF ID to the functions which process
the received messages.
- All relative functions are appended with a new parameter "vrf_id".
* Suppress the messages in a VRF which a client does not care:
Some clients may not care about the information in the VRF X, and
zebra should not send the messages in the VRF X to those clients.
Extra flags are used to indicate which VRF is registered by a client,
and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client
can unregister a VRF when it does not need any information in that
VRF.
A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF
will automatically register to that VRF.
- lib/vrf:
A new utility "VRF bit-map" is provided to manage the flags for
VRFs, one bit per VRF ID.
- Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a
bit-map;
- Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag
in the given bit-map, corresponding to the given VRF ID;
- Use vrf_bitmap_check() to test whether the flag, in the given
bit-map and for the given VRF ID, is set.
- Client side:
- In "struct zclient", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
default_information
These flags are extended for each VRF, and controlled by the
clients themselves (or with the help of zclient_redistribute()
and zclient_redistribute_default()).
- Zebra side:
- In "struct zserv", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
redist_default
ifinfo
ridinfo
These flags are extended for each VRF, as the VRF registration
flags. They are maintained on receiving a ZEBRA_XXX_ADD or
ZEBRA_XXX_DELETE message.
When sending an interface/address/route/router-id message in
a VRF to a client, if the corresponding VRF registration flag
is not set, this message will not be dropped by zebra.
- A new function zread_vrf_unregister() is introduced to process
the new command ZEBRA_VRF_UNREGISTER. All the VRF registration
flags are cleared for the requested VRF.
Those clients, who support only the default VRF, will never receive
a message in a non-default VRF, thanks to the filter in zebra.
* New callback for the event of successful connection to zebra:
- zclient_start() is splitted, keeping only the code of connecting
to zebra.
- Now zclient_init()=>zclient_connect()=>zclient_start() operations
are purely dealing with the connection to zbera.
- Once zebra is successfully connected, at the end of zclient_start(),
a new callback is used to inform the client about connection.
- Till now, in the callback of connect-to-zebra event, all clients
send messages to zebra to request the router-id/interface/routes
information in the default VRF.
Of corse in future the client can do anything it wants in this
callback. For example, it may send requests for both default VRF
and some non-default VRFs.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
Conflicts:
lib/zclient.h
lib/zebra.h
zebra/zserv.c
zebra/zserv.h
Conflicts:
bgpd/bgp_nexthop.c
bgpd/bgp_nht.c
bgpd/bgp_zebra.c
isisd/isis_zebra.c
lib/zclient.c
lib/zclient.h
lib/zebra.h
nhrpd/nhrp_interface.c
nhrpd/nhrp_route.c
nhrpd/nhrpd.h
ospf6d/ospf6_zebra.c
ospf6d/ospf6_zebra.h
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
pimd/pim_zebra.c
pimd/pim_zlookup.c
ripd/rip_zebra.c
ripngd/ripng_zebra.c
zebra/redistribute.c
zebra/rt_netlink.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h
zebra/zserv.c
zebra/zserv.h
2014-10-16 03:52:36 +02:00
|
|
|
zclient->ibuf, vrf_id);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
if (c == NULL)
|
|
|
|
return 0;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2004-09-14 15:54:30 +02:00
|
|
|
#ifdef EXTREME_DEBUG
|
|
|
|
p = c->address;
|
2015-11-23 21:44:34 +01:00
|
|
|
prefix2str(p, buf, sizeof(buf));
|
2004-09-14 15:54:30 +02:00
|
|
|
|
|
|
|
if (p->family == AF_INET)
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug("disconnected IP address %s", buf);
|
2004-09-14 15:54:30 +02:00
|
|
|
if (p->family == AF_INET6)
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug("disconnected IPv6 address %s", buf);
|
2004-09-14 15:54:30 +02:00
|
|
|
#endif /* EXTREME_DEBUG */
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2020-10-08 19:05:08 +02:00
|
|
|
if (if_is_operative(c->ifp)) {
|
|
|
|
circuit = circuit_scan_by_ifp(c->ifp);
|
|
|
|
if (circuit)
|
|
|
|
isis_circuit_del_addr(circuit, c);
|
|
|
|
}
|
|
|
|
|
2019-10-30 01:16:28 +01:00
|
|
|
connected_free(&c);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-05-03 21:42:59 +02:00
|
|
|
static int isis_zebra_link_params(ZAPI_CALLBACK_ARGS)
|
2016-04-19 19:03:05 +02:00
|
|
|
{
|
|
|
|
struct interface *ifp;
|
|
|
|
|
2019-01-18 19:06:00 +01:00
|
|
|
ifp = zebra_interface_link_params_read(zclient->ibuf, vrf_id);
|
2016-04-19 19:03:05 +02:00
|
|
|
|
|
|
|
if (ifp == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Update TE TLV */
|
|
|
|
isis_mpls_te_update(ifp);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-06-19 20:46:12 +02:00
|
|
|
void isis_zebra_route_add_route(struct isis *isis,
|
|
|
|
struct prefix *prefix,
|
2019-08-08 00:42:18 +02:00
|
|
|
struct prefix_ipv6 *src_p,
|
|
|
|
struct isis_route_info *route_info)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2017-08-21 02:18:36 +02:00
|
|
|
struct zapi_route api;
|
|
|
|
struct zapi_nexthop *api_nh;
|
2003-12-23 09:09:43 +01:00
|
|
|
struct isis_nexthop *nexthop;
|
|
|
|
struct listnode *node;
|
2017-08-21 02:18:36 +02:00
|
|
|
int count = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-08-08 00:42:18 +02:00
|
|
|
if (zclient->sock < 0)
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-21 02:18:36 +02:00
|
|
|
memset(&api, 0, sizeof(api));
|
2020-06-19 20:46:12 +02:00
|
|
|
api.vrf_id = isis->vrf_id;
|
2018-03-22 15:01:08 +01:00
|
|
|
api.type = PROTO_TYPE;
|
2017-08-21 02:18:36 +02:00
|
|
|
api.safi = SAFI_UNICAST;
|
|
|
|
api.prefix = *prefix;
|
2018-07-26 22:53:08 +02:00
|
|
|
if (src_p && src_p->prefixlen) {
|
|
|
|
api.src_prefix = *src_p;
|
|
|
|
SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
|
|
|
|
}
|
2017-08-21 02:18:36 +02:00
|
|
|
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
|
|
|
|
SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
|
|
|
|
api.metric = route_info->cost;
|
2003-12-23 12:51:08 +01:00
|
|
|
#if 0
|
2017-08-21 02:18:36 +02:00
|
|
|
SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
|
|
|
|
api.distance = route_info->depth;
|
2003-12-23 12:51:08 +01:00
|
|
|
#endif
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2017-08-21 02:29:35 +02:00
|
|
|
/* Nexthops */
|
2019-08-06 22:43:46 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, nexthop)) {
|
|
|
|
if (count >= MULTIPATH_NUM)
|
|
|
|
break;
|
|
|
|
api_nh = &api.nexthops[count];
|
|
|
|
if (fabricd)
|
2019-11-13 22:06:06 +01:00
|
|
|
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
|
2020-06-19 20:46:12 +02:00
|
|
|
api_nh->vrf_id = isis->vrf_id;
|
2019-08-06 22:43:46 +02:00
|
|
|
|
|
|
|
switch (nexthop->family) {
|
|
|
|
case AF_INET:
|
2017-08-21 02:29:35 +02:00
|
|
|
/* FIXME: can it be ? */
|
2019-08-06 22:43:46 +02:00
|
|
|
if (nexthop->ip.ipv4.s_addr != INADDR_ANY) {
|
2017-08-21 02:29:35 +02:00
|
|
|
api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
|
2019-08-06 22:43:46 +02:00
|
|
|
api_nh->gate.ipv4 = nexthop->ip.ipv4;
|
2017-08-21 02:29:35 +02:00
|
|
|
} else {
|
|
|
|
api_nh->type = NEXTHOP_TYPE_IFINDEX;
|
|
|
|
}
|
2019-08-06 22:43:46 +02:00
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
if (!IN6_IS_ADDR_LINKLOCAL(&nexthop->ip.ipv6)
|
|
|
|
&& !IN6_IS_ADDR_UNSPECIFIED(&nexthop->ip.ipv6)) {
|
2017-08-21 02:29:35 +02:00
|
|
|
continue;
|
|
|
|
}
|
2019-08-06 22:43:46 +02:00
|
|
|
api_nh->gate.ipv6 = nexthop->ip.ipv6;
|
2017-08-21 02:29:35 +02:00
|
|
|
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
2019-08-06 22:43:46 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
flog_err(EC_LIB_DEVELOPMENT,
|
|
|
|
"%s: unknown address family [%d]", __func__,
|
|
|
|
nexthop->family);
|
|
|
|
exit(1);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2019-08-06 22:43:46 +02:00
|
|
|
|
|
|
|
api_nh->ifindex = nexthop->ifindex;
|
|
|
|
count++;
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2017-08-21 02:18:36 +02:00
|
|
|
if (!count)
|
|
|
|
return;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2017-08-21 02:18:36 +02:00
|
|
|
api.nexthop_num = count;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2017-08-21 02:18:36 +02:00
|
|
|
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2020-06-19 20:46:12 +02:00
|
|
|
void isis_zebra_route_del_route(struct isis *isis,
|
|
|
|
struct prefix *prefix,
|
2019-08-08 00:42:18 +02:00
|
|
|
struct prefix_ipv6 *src_p,
|
|
|
|
struct isis_route_info *route_info)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2017-08-21 02:18:36 +02:00
|
|
|
struct zapi_route api;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-08-08 00:42:18 +02:00
|
|
|
if (zclient->sock < 0)
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-21 02:18:36 +02:00
|
|
|
memset(&api, 0, sizeof(api));
|
2020-06-19 20:46:12 +02:00
|
|
|
api.vrf_id = isis->vrf_id;
|
2018-03-22 15:01:08 +01:00
|
|
|
api.type = PROTO_TYPE;
|
2012-04-12 08:56:03 +02:00
|
|
|
api.safi = SAFI_UNICAST;
|
2017-08-21 02:18:36 +02:00
|
|
|
api.prefix = *prefix;
|
2018-07-26 22:53:08 +02:00
|
|
|
if (src_p && src_p->prefixlen) {
|
|
|
|
api.src_prefix = *src_p;
|
|
|
|
SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
|
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2017-08-21 02:18:36 +02:00
|
|
|
zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2020-05-04 19:39:20 +02:00
|
|
|
/**
|
|
|
|
* Install Prefix-SID in the forwarding plane through Zebra.
|
|
|
|
*
|
|
|
|
* @param srp Segment Routing Prefix-SID
|
|
|
|
*/
|
2020-05-04 18:26:21 +02:00
|
|
|
static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
|
2019-08-04 03:02:37 +02:00
|
|
|
{
|
|
|
|
struct zapi_labels zl;
|
2020-03-03 16:59:33 +01:00
|
|
|
struct zapi_nexthop *znh;
|
2019-08-04 03:02:37 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct isis_nexthop *nexthop;
|
|
|
|
struct interface *ifp;
|
|
|
|
|
|
|
|
/* Prepare message. */
|
|
|
|
memset(&zl, 0, sizeof(zl));
|
|
|
|
zl.type = ZEBRA_LSP_ISIS_SR;
|
2020-05-03 20:01:20 +02:00
|
|
|
zl.local_label = srp->input_label;
|
2019-08-04 03:02:37 +02:00
|
|
|
|
|
|
|
switch (srp->type) {
|
|
|
|
case ISIS_SR_PREFIX_LOCAL:
|
|
|
|
ifp = if_lookup_by_name("lo", VRF_DEFAULT);
|
|
|
|
if (!ifp) {
|
|
|
|
zlog_warn(
|
|
|
|
"%s: couldn't install Prefix-SID %pFX: loopback interface not found",
|
|
|
|
__func__, &srp->prefix);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
znh = &zl.nexthops[zl.nexthop_num++];
|
|
|
|
znh->type = NEXTHOP_TYPE_IFINDEX;
|
|
|
|
znh->ifindex = ifp->ifindex;
|
2020-03-03 16:59:33 +01:00
|
|
|
znh->label_num = 1;
|
|
|
|
znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
|
2019-08-04 03:02:37 +02:00
|
|
|
break;
|
|
|
|
case ISIS_SR_PREFIX_REMOTE:
|
|
|
|
/* Update route in the RIB too. */
|
|
|
|
SET_FLAG(zl.message, ZAPI_LABELS_FTN);
|
|
|
|
zl.route.prefix = srp->prefix;
|
|
|
|
zl.route.type = ZEBRA_ROUTE_ISIS;
|
|
|
|
zl.route.instance = 0;
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, node,
|
|
|
|
nexthop)) {
|
|
|
|
if (nexthop->sr.label == MPLS_INVALID_LABEL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (zl.nexthop_num >= MULTIPATH_NUM)
|
|
|
|
break;
|
|
|
|
|
|
|
|
znh = &zl.nexthops[zl.nexthop_num++];
|
|
|
|
znh->type = (srp->prefix.family == AF_INET)
|
|
|
|
? NEXTHOP_TYPE_IPV4_IFINDEX
|
|
|
|
: NEXTHOP_TYPE_IPV6_IFINDEX;
|
2020-03-03 16:59:33 +01:00
|
|
|
znh->gate = nexthop->ip;
|
2019-08-04 03:02:37 +02:00
|
|
|
znh->ifindex = nexthop->ifindex;
|
2020-03-03 16:59:33 +01:00
|
|
|
znh->label_num = 1;
|
|
|
|
znh->labels[0] = nexthop->sr.label;
|
2019-08-04 03:02:37 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send message to zebra. */
|
|
|
|
(void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl);
|
|
|
|
}
|
|
|
|
|
2020-05-04 19:39:20 +02:00
|
|
|
/**
|
|
|
|
* Uninstall Prefix-SID from the forwarding plane through Zebra.
|
|
|
|
*
|
|
|
|
* @param srp Segment Routing Prefix-SID
|
|
|
|
*/
|
2020-05-04 18:26:21 +02:00
|
|
|
static void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp)
|
2019-08-04 03:02:37 +02:00
|
|
|
{
|
|
|
|
struct zapi_labels zl;
|
|
|
|
|
|
|
|
/* Prepare message. */
|
|
|
|
memset(&zl, 0, sizeof(zl));
|
|
|
|
zl.type = ZEBRA_LSP_ISIS_SR;
|
2020-05-03 20:01:20 +02:00
|
|
|
zl.local_label = srp->input_label;
|
2019-08-04 03:02:37 +02:00
|
|
|
|
|
|
|
if (srp->type == ISIS_SR_PREFIX_REMOTE) {
|
|
|
|
/* Update route in the RIB too. */
|
|
|
|
SET_FLAG(zl.message, ZAPI_LABELS_FTN);
|
|
|
|
zl.route.prefix = srp->prefix;
|
|
|
|
zl.route.type = ZEBRA_ROUTE_ISIS;
|
|
|
|
zl.route.instance = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send message to zebra. */
|
|
|
|
(void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
|
|
|
|
}
|
|
|
|
|
2020-05-04 19:39:20 +02:00
|
|
|
/**
|
|
|
|
* Send Prefix-SID to ZEBRA for installation or deletion.
|
|
|
|
*
|
|
|
|
* @param cmd ZEBRA_MPLS_LABELS_REPLACE or ZEBRA_ROUTE_DELETE
|
|
|
|
* @param srp Segment Routing Prefix-SID
|
|
|
|
*/
|
2020-05-04 18:26:21 +02:00
|
|
|
void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (cmd != ZEBRA_MPLS_LABELS_REPLACE
|
|
|
|
&& cmd != ZEBRA_MPLS_LABELS_DELETE) {
|
|
|
|
flog_warn(EC_LIB_DEVELOPMENT, "%s: wrong ZEBRA command",
|
|
|
|
__func__);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sr_debug(" |- %s label %u for prefix %pFX",
|
|
|
|
cmd == ZEBRA_MPLS_LABELS_REPLACE ? "Update" : "Delete",
|
|
|
|
srp->input_label, &srp->prefix);
|
|
|
|
|
|
|
|
if (cmd == ZEBRA_MPLS_LABELS_REPLACE)
|
|
|
|
isis_zebra_prefix_install_prefix_sid(srp);
|
|
|
|
else
|
|
|
|
isis_zebra_uninstall_prefix_sid(srp);
|
|
|
|
}
|
|
|
|
|
2020-05-04 19:39:20 +02:00
|
|
|
/**
|
|
|
|
* Send (LAN)-Adjacency-SID to ZEBRA for installation or deletion.
|
|
|
|
*
|
|
|
|
* @param cmd ZEBRA_MPLS_LABELS_ADD or ZEBRA_ROUTE_DELETE
|
|
|
|
* @param sra Segment Routing Adjacency-SID
|
|
|
|
*/
|
2020-05-04 18:26:21 +02:00
|
|
|
void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra)
|
|
|
|
{
|
|
|
|
struct zapi_labels zl;
|
|
|
|
struct zapi_nexthop *znh;
|
|
|
|
|
|
|
|
if (cmd != ZEBRA_MPLS_LABELS_ADD && cmd != ZEBRA_MPLS_LABELS_DELETE) {
|
|
|
|
flog_warn(EC_LIB_DEVELOPMENT, "%s: wrong ZEBRA command",
|
|
|
|
__func__);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sr_debug(" |- %s label %u for interface %s",
|
|
|
|
cmd == ZEBRA_MPLS_LABELS_ADD ? "Add" : "Delete",
|
|
|
|
sra->nexthop.label, sra->adj->circuit->interface->name);
|
|
|
|
|
|
|
|
memset(&zl, 0, sizeof(zl));
|
|
|
|
zl.type = ZEBRA_LSP_ISIS_SR;
|
|
|
|
zl.local_label = sra->nexthop.label;
|
|
|
|
zl.nexthop_num = 1;
|
|
|
|
znh = &zl.nexthops[0];
|
|
|
|
znh->gate = sra->nexthop.address;
|
|
|
|
znh->type = (sra->nexthop.family == AF_INET)
|
|
|
|
? NEXTHOP_TYPE_IPV4_IFINDEX
|
|
|
|
: NEXTHOP_TYPE_IPV6_IFINDEX;
|
|
|
|
znh->ifindex = sra->adj->circuit->interface->ifindex;
|
|
|
|
znh->label_num = 1;
|
|
|
|
znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
|
|
|
|
|
|
|
|
(void)zebra_send_mpls_labels(zclient, cmd, &zl);
|
|
|
|
}
|
|
|
|
|
2019-05-03 21:42:59 +02:00
|
|
|
static int isis_zebra_read(ZAPI_CALLBACK_ARGS)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2017-08-21 03:10:50 +02:00
|
|
|
struct zapi_route api;
|
2020-07-13 14:37:59 +02:00
|
|
|
struct isis *isis = NULL;
|
|
|
|
|
|
|
|
isis = isis_lookup_by_vrfid(vrf_id);
|
|
|
|
|
|
|
|
if (isis == NULL)
|
|
|
|
return -1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-21 03:10:50 +02:00
|
|
|
if (zapi_route_decode(zclient->ibuf, &api) < 0)
|
|
|
|
return -1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-02-22 16:20:51 +01:00
|
|
|
if (api.prefix.family == AF_INET6
|
|
|
|
&& IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
|
|
|
|
return 0;
|
|
|
|
|
2015-11-12 14:24:22 +01:00
|
|
|
/*
|
|
|
|
* Avoid advertising a false default reachability. (A default
|
|
|
|
* route installed by IS-IS gets redistributed from zebra back
|
|
|
|
* into IS-IS causing us to start advertising default reachabity
|
|
|
|
* without this check)
|
|
|
|
*/
|
2018-07-22 21:49:02 +02:00
|
|
|
if (api.prefix.prefixlen == 0
|
|
|
|
&& api.src_prefix.prefixlen == 0
|
2018-03-22 15:01:08 +01:00
|
|
|
&& api.type == PROTO_TYPE) {
|
2019-05-03 21:42:59 +02:00
|
|
|
cmd = ZEBRA_REDISTRIBUTE_ROUTE_DEL;
|
2018-07-22 21:49:02 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-05-03 21:42:59 +02:00
|
|
|
if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
|
2020-07-13 14:37:59 +02:00
|
|
|
isis_redist_add(isis, api.type, &api.prefix, &api.src_prefix,
|
2018-07-22 21:49:02 +02:00
|
|
|
api.distance, api.metric);
|
2015-11-12 14:24:22 +01:00
|
|
|
else
|
2020-07-13 14:37:59 +02:00
|
|
|
isis_redist_delete(isis, api.type, &api.prefix,
|
|
|
|
&api.src_prefix);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int isis_distribute_list_update(int routetype)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-20 22:47:54 +02:00
|
|
|
void isis_zebra_redistribute_set(afi_t afi, int type)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2015-11-12 14:24:22 +01:00
|
|
|
if (type == DEFAULT_ROUTE)
|
|
|
|
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
|
2019-01-11 22:20:13 +01:00
|
|
|
zclient, afi, VRF_DEFAULT);
|
2015-11-12 14:24:22 +01:00
|
|
|
else
|
2017-06-20 22:47:54 +02:00
|
|
|
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
|
|
|
|
0, VRF_DEFAULT);
|
2015-11-12 14:24:22 +01:00
|
|
|
}
|
|
|
|
|
2017-06-20 22:47:54 +02:00
|
|
|
void isis_zebra_redistribute_unset(afi_t afi, int type)
|
2015-11-12 14:24:22 +01:00
|
|
|
{
|
|
|
|
if (type == DEFAULT_ROUTE)
|
|
|
|
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
|
2019-01-11 22:20:13 +01:00
|
|
|
zclient, afi, VRF_DEFAULT);
|
2015-11-12 14:24:22 +01:00
|
|
|
else
|
2017-06-20 22:47:54 +02:00
|
|
|
zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
|
|
|
|
type, 0, VRF_DEFAULT);
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2020-04-10 17:12:48 +02:00
|
|
|
/* Label Manager Functions */
|
|
|
|
|
2020-06-04 18:03:04 +02:00
|
|
|
/**
|
|
|
|
* Check if Label Manager is Ready or not.
|
|
|
|
*
|
|
|
|
* @return True if Label Manager is ready, False otherwise
|
|
|
|
*/
|
|
|
|
bool isis_zebra_label_manager_ready(void)
|
|
|
|
{
|
|
|
|
return (zclient_sync->sock > 0);
|
|
|
|
}
|
|
|
|
|
2020-04-10 17:12:48 +02:00
|
|
|
/**
|
|
|
|
* Request Label Range to the Label Manager.
|
|
|
|
*
|
|
|
|
* @param base base label of the label range to request
|
|
|
|
* @param chunk_size size of the label range to request
|
|
|
|
*
|
|
|
|
* @return 0 on success, -1 on failure
|
|
|
|
*/
|
2019-08-04 03:02:37 +02:00
|
|
|
int isis_zebra_request_label_range(uint32_t base, uint32_t chunk_size)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
uint32_t start, end;
|
|
|
|
|
2020-06-04 18:03:04 +02:00
|
|
|
if (zclient_sync->sock < 0)
|
|
|
|
return -1;
|
2019-08-04 03:02:37 +02:00
|
|
|
|
|
|
|
ret = lm_get_label_chunk(zclient_sync, 0, base, chunk_size, &start,
|
|
|
|
&end);
|
|
|
|
if (ret < 0) {
|
|
|
|
zlog_warn("%s: error getting label range!", __func__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-04-10 17:12:48 +02:00
|
|
|
/**
|
|
|
|
* Release Label Range to the Label Manager.
|
|
|
|
*
|
|
|
|
* @param start start of label range to release
|
|
|
|
* @param end end of label range to release
|
|
|
|
*
|
2020-06-04 18:03:04 +02:00
|
|
|
* @return 0 on success, -1 otherwise
|
2020-04-10 17:12:48 +02:00
|
|
|
*/
|
2020-06-04 18:03:04 +02:00
|
|
|
int isis_zebra_release_label_range(uint32_t start, uint32_t end)
|
2019-08-04 03:02:37 +02:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2020-06-04 18:03:04 +02:00
|
|
|
if (zclient_sync->sock < 0)
|
2019-08-04 03:02:37 +02:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
ret = lm_release_label_chunk(zclient_sync, start, end);
|
|
|
|
if (ret < 0) {
|
|
|
|
zlog_warn("%s: error releasing label range!", __func__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-04-10 17:12:48 +02:00
|
|
|
/**
|
|
|
|
* Connect to the Label Manager.
|
2020-06-04 18:03:04 +02:00
|
|
|
*
|
|
|
|
* @return 0 on success, -1 otherwise
|
2020-04-10 17:12:48 +02:00
|
|
|
*/
|
2020-06-04 18:03:04 +02:00
|
|
|
int isis_zebra_label_manager_connect(void)
|
2019-08-04 03:02:37 +02:00
|
|
|
{
|
|
|
|
/* Connect to label manager. */
|
2020-06-04 18:03:04 +02:00
|
|
|
if (zclient_socket_connect(zclient_sync) < 0) {
|
|
|
|
zlog_warn("%s: failed connecting synchronous zclient!",
|
2019-08-04 03:02:37 +02:00
|
|
|
__func__);
|
2020-06-04 18:03:04 +02:00
|
|
|
return -1;
|
2019-08-04 03:02:37 +02:00
|
|
|
}
|
2020-04-10 17:12:48 +02:00
|
|
|
/* make socket non-blocking */
|
2019-08-04 03:02:37 +02:00
|
|
|
set_nonblocking(zclient_sync->sock);
|
2020-04-10 17:12:48 +02:00
|
|
|
|
|
|
|
/* Send hello to notify zebra this is a synchronous client */
|
2020-06-04 18:03:04 +02:00
|
|
|
if (zclient_send_hello(zclient_sync) < 0) {
|
|
|
|
zlog_warn("%s: failed sending hello for synchronous zclient!",
|
|
|
|
__func__);
|
|
|
|
close(zclient_sync->sock);
|
|
|
|
zclient_sync->sock = -1;
|
|
|
|
return -1;
|
2020-04-10 17:12:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Connect to label manager */
|
2020-06-04 18:03:04 +02:00
|
|
|
if (lm_label_manager_connect(zclient_sync, 0) != 0) {
|
|
|
|
zlog_warn("%s: failed connecting to label manager!", __func__);
|
|
|
|
if (zclient_sync->sock > 0) {
|
|
|
|
close(zclient_sync->sock);
|
|
|
|
zclient_sync->sock = -1;
|
|
|
|
}
|
|
|
|
return -1;
|
2019-08-04 03:02:37 +02:00
|
|
|
}
|
|
|
|
|
2020-06-04 18:03:04 +02:00
|
|
|
sr_debug("ISIS-Sr: Successfully connected to the Label Manager");
|
|
|
|
|
|
|
|
return 0;
|
2019-08-04 03:02:37 +02:00
|
|
|
}
|
|
|
|
|
2020-08-18 09:26:51 +02:00
|
|
|
void isis_zebra_vrf_register(struct isis *isis)
|
|
|
|
{
|
|
|
|
if (!zclient || zclient->sock < 0 || !isis)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (isis->vrf_id != VRF_UNKNOWN) {
|
|
|
|
if (IS_DEBUG_EVENTS)
|
|
|
|
zlog_debug("%s: Register VRF %s id %u", __func__,
|
|
|
|
isis->name, isis->vrf_id);
|
|
|
|
zclient_send_reg_requests(zclient, isis->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
|
|
|
static void isis_zebra_connected(struct zclient *zclient)
|
|
|
|
{
|
2016-02-12 20:37:33 +01:00
|
|
|
zclient_send_reg_requests(zclient, VRF_DEFAULT);
|
*: add VRF ID in the API message header
The API messages are used by zebra to exchange the interfaces, addresses,
routes and router-id information with its clients. To distinguish which
VRF the information belongs to, a new field "VRF ID" is added in the
message header. And hence the message version is increased to 3.
* The new field "VRF ID" in the message header:
Length (2 bytes)
Marker (1 byte)
Version (1 byte)
VRF ID (2 bytes, newly added)
Command (2 bytes)
- Client side:
- zclient_create_header() adds the VRF ID in the message header.
- zclient_read() extracts and validates the VRF ID from the header,
and passes the VRF ID to the callback functions registered to
the API messages.
- All relative functions are appended with a new parameter "vrf_id",
including all the callback functions.
- "vrf_id" is also added to "struct zapi_ipv4" and "struct zapi_ipv6".
Clients need to correctly set the VRF ID when using the API
functions zapi_ipv4_route() and zapi_ipv6_route().
- Till now all messages sent from a client have the default VRF ID
"0" in the header.
- The HELLO message is special, which is used as the heart-beat of
a client, and has no relation with VRF. The VRF ID in the HELLO
message header will always be 0 and ignored by zebra.
- Zebra side:
- zserv_create_header() adds the VRF ID in the message header.
- zebra_client_read() extracts and validates the VRF ID from the
header, and passes the VRF ID to the functions which process
the received messages.
- All relative functions are appended with a new parameter "vrf_id".
* Suppress the messages in a VRF which a client does not care:
Some clients may not care about the information in the VRF X, and
zebra should not send the messages in the VRF X to those clients.
Extra flags are used to indicate which VRF is registered by a client,
and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client
can unregister a VRF when it does not need any information in that
VRF.
A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF
will automatically register to that VRF.
- lib/vrf:
A new utility "VRF bit-map" is provided to manage the flags for
VRFs, one bit per VRF ID.
- Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a
bit-map;
- Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag
in the given bit-map, corresponding to the given VRF ID;
- Use vrf_bitmap_check() to test whether the flag, in the given
bit-map and for the given VRF ID, is set.
- Client side:
- In "struct zclient", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
default_information
These flags are extended for each VRF, and controlled by the
clients themselves (or with the help of zclient_redistribute()
and zclient_redistribute_default()).
- Zebra side:
- In "struct zserv", the following flags are changed from
"u_char" to "vrf_bitmap_t":
redist[ZEBRA_ROUTE_MAX]
redist_default
ifinfo
ridinfo
These flags are extended for each VRF, as the VRF registration
flags. They are maintained on receiving a ZEBRA_XXX_ADD or
ZEBRA_XXX_DELETE message.
When sending an interface/address/route/router-id message in
a VRF to a client, if the corresponding VRF registration flag
is not set, this message will not be dropped by zebra.
- A new function zread_vrf_unregister() is introduced to process
the new command ZEBRA_VRF_UNREGISTER. All the VRF registration
flags are cleared for the requested VRF.
Those clients, who support only the default VRF, will never receive
a message in a non-default VRF, thanks to the filter in zebra.
* New callback for the event of successful connection to zebra:
- zclient_start() is splitted, keeping only the code of connecting
to zebra.
- Now zclient_init()=>zclient_connect()=>zclient_start() operations
are purely dealing with the connection to zbera.
- Once zebra is successfully connected, at the end of zclient_start(),
a new callback is used to inform the client about connection.
- Till now, in the callback of connect-to-zebra event, all clients
send messages to zebra to request the router-id/interface/routes
information in the default VRF.
Of corse in future the client can do anything it wants in this
callback. For example, it may send requests for both default VRF
and some non-default VRFs.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
Conflicts:
lib/zclient.h
lib/zebra.h
zebra/zserv.c
zebra/zserv.h
Conflicts:
bgpd/bgp_nexthop.c
bgpd/bgp_nht.c
bgpd/bgp_zebra.c
isisd/isis_zebra.c
lib/zclient.c
lib/zclient.h
lib/zebra.h
nhrpd/nhrp_interface.c
nhrpd/nhrp_route.c
nhrpd/nhrpd.h
ospf6d/ospf6_zebra.c
ospf6d/ospf6_zebra.h
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
pimd/pim_zebra.c
pimd/pim_zlookup.c
ripd/rip_zebra.c
ripngd/ripng_zebra.c
zebra/redistribute.c
zebra/rt_netlink.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h
zebra/zserv.c
zebra/zserv.h
2014-10-16 03:52:36 +02:00
|
|
|
}
|
|
|
|
|
2020-07-22 20:32:35 +02:00
|
|
|
/*
|
|
|
|
* opaque messages between processes
|
|
|
|
*/
|
|
|
|
static int isis_opaque_msg_handler(ZAPI_CALLBACK_ARGS)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct zapi_opaque_msg info;
|
|
|
|
struct ldp_igp_sync_if_state state;
|
|
|
|
struct ldp_igp_sync_announce announce;
|
|
|
|
struct ldp_igp_sync_hello hello;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
s = zclient->ibuf;
|
|
|
|
if (zclient_opaque_decode(s, &info) != 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
switch (info.type) {
|
|
|
|
case LDP_IGP_SYNC_IF_STATE_UPDATE:
|
|
|
|
STREAM_GET(&state, s, sizeof(state));
|
|
|
|
ret = isis_ldp_sync_state_update(state);
|
|
|
|
break;
|
|
|
|
case LDP_IGP_SYNC_ANNOUNCE_UPDATE:
|
|
|
|
STREAM_GET(&announce, s, sizeof(announce));
|
|
|
|
ret = isis_ldp_sync_announce_update(announce);
|
|
|
|
break;
|
|
|
|
case LDP_IGP_SYNC_HELLO_UPDATE:
|
|
|
|
STREAM_GET(&hello, s, sizeof(hello));
|
|
|
|
ret = isis_ldp_sync_hello_update(hello);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream_failure:
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-08-04 03:02:37 +02:00
|
|
|
void isis_zebra_init(struct thread_master *master, int instance)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2019-08-04 03:02:37 +02:00
|
|
|
/* Initialize asynchronous zclient. */
|
2018-11-02 13:54:58 +01:00
|
|
|
zclient = zclient_new(master, &zclient_options_default);
|
2018-03-22 15:01:08 +01:00
|
|
|
zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs);
|
*: 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
|
|
|
zclient->zebra_connected = isis_zebra_connected;
|
2004-10-03 20:18:34 +02:00
|
|
|
zclient->router_id_update = isis_router_id_update_zebra;
|
2003-12-23 09:09:43 +01:00
|
|
|
zclient->interface_address_add = isis_zebra_if_address_add;
|
|
|
|
zclient->interface_address_delete = isis_zebra_if_address_del;
|
2016-04-19 19:03:05 +02:00
|
|
|
zclient->interface_link_params = isis_zebra_link_params;
|
2017-08-21 03:10:50 +02:00
|
|
|
zclient->redistribute_route_add = isis_zebra_read;
|
|
|
|
zclient->redistribute_route_del = isis_zebra_read;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-08-04 03:02:37 +02:00
|
|
|
/* Initialize special zclient for synchronous message exchanges. */
|
2020-04-10 17:12:48 +02:00
|
|
|
struct zclient_options options = zclient_options_default;
|
|
|
|
options.synchronous = true;
|
|
|
|
zclient_sync = zclient_new(master, &options);
|
2019-08-04 03:02:37 +02:00
|
|
|
zclient_sync->sock = -1;
|
|
|
|
zclient_sync->redist_default = ZEBRA_ROUTE_ISIS;
|
|
|
|
zclient_sync->instance = instance;
|
2020-04-10 17:12:48 +02:00
|
|
|
/*
|
|
|
|
* session_id must be different from default value (0) to distinguish
|
|
|
|
* the asynchronous socket from the synchronous one
|
|
|
|
*/
|
|
|
|
zclient_sync->session_id = 1;
|
2019-08-04 03:02:37 +02:00
|
|
|
zclient_sync->privs = &isisd_privs;
|
2020-07-22 20:32:35 +02:00
|
|
|
|
|
|
|
zclient->opaque_msg_handler = isis_opaque_msg_handler;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
2017-06-30 16:31:09 +02:00
|
|
|
|
|
|
|
void isis_zebra_stop(void)
|
|
|
|
{
|
2020-06-04 18:03:04 +02:00
|
|
|
zclient_stop(zclient_sync);
|
|
|
|
zclient_free(zclient_sync);
|
2017-06-30 16:31:09 +02:00
|
|
|
zclient_stop(zclient);
|
|
|
|
zclient_free(zclient);
|
2017-09-12 04:05:16 +02:00
|
|
|
frr_fini();
|
2017-06-30 16:31:09 +02:00
|
|
|
}
|