version 1.1.1.2, 2012/10/09 09:22:28
|
version 1.1.1.3, 2016/11/02 10:09:10
|
Line 4
|
Line 4
|
* Copyright (C) 2001,2002 Sampo Saaristo |
* Copyright (C) 2001,2002 Sampo Saaristo |
* Tampere University of Technology |
* Tampere University of Technology |
* Institute of Communications Engineering |
* Institute of Communications Engineering |
|
* Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org> |
* |
* |
* This program is free software; you can redistribute it and/or modify it |
* 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 |
* under the terms of the GNU General Public Licenseas published by the Free |
Line 32
|
Line 33
|
#include "zclient.h" |
#include "zclient.h" |
#include "stream.h" |
#include "stream.h" |
#include "linklist.h" |
#include "linklist.h" |
|
#include "vrf.h" |
|
|
#include "isisd/dict.h" |
#include "isisd/dict.h" |
#include "isisd/isis_constants.h" |
#include "isisd/isis_constants.h" |
Line 52 struct zclient *zclient = NULL;
|
Line 54 struct zclient *zclient = NULL;
|
/* Router-id update message from zebra. */ |
/* Router-id update message from zebra. */ |
static int |
static int |
isis_router_id_update_zebra (int command, struct zclient *zclient, |
isis_router_id_update_zebra (int command, struct zclient *zclient, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
struct isis_area *area; |
struct isis_area *area; |
struct listnode *node; |
struct listnode *node; |
Line 71 isis_router_id_update_zebra (int command, struct zclie
|
Line 73 isis_router_id_update_zebra (int command, struct zclie
|
} |
} |
|
|
static int |
static int |
isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length) | isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
|
|
ifp = zebra_interface_add_read (zclient->ibuf); | ifp = zebra_interface_add_read (zclient->ibuf, vrf_id); |
|
|
if (isis->debugs & DEBUG_ZEBRA) |
if (isis->debugs & DEBUG_ZEBRA) |
zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d", |
zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d", |
Line 88 isis_zebra_if_add (int command, struct zclient *zclien
|
Line 91 isis_zebra_if_add (int command, struct zclient *zclien
|
} |
} |
|
|
static int |
static int |
isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length) | isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length, |
| vrf_id_t vrf_id) |
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
struct stream *s; |
struct stream *s; |
|
|
s = zclient->ibuf; |
s = zclient->ibuf; |
ifp = zebra_interface_state_read (s); | ifp = zebra_interface_state_read (s, vrf_id); |
|
|
if (!ifp) |
if (!ifp) |
return 0; |
return 0; |
Line 120 isis_zebra_if_del (int command, struct zclient *zclien
|
Line 124 isis_zebra_if_del (int command, struct zclient *zclien
|
|
|
static int |
static int |
isis_zebra_if_state_up (int command, struct zclient *zclient, |
isis_zebra_if_state_up (int command, struct zclient *zclient, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
|
|
ifp = zebra_interface_state_read (zclient->ibuf); | ifp = zebra_interface_state_read (zclient->ibuf, vrf_id); |
|
|
if (ifp == NULL) |
if (ifp == NULL) |
return 0; |
return 0; |
Line 136 isis_zebra_if_state_up (int command, struct zclient *z
|
Line 140 isis_zebra_if_state_up (int command, struct zclient *z
|
|
|
static int |
static int |
isis_zebra_if_state_down (int command, struct zclient *zclient, |
isis_zebra_if_state_down (int command, struct zclient *zclient, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
struct isis_circuit *circuit; |
struct isis_circuit *circuit; |
|
|
ifp = zebra_interface_state_read (zclient->ibuf); | ifp = zebra_interface_state_read (zclient->ibuf, vrf_id); |
|
|
if (ifp == NULL) |
if (ifp == NULL) |
return 0; |
return 0; |
Line 156 isis_zebra_if_state_down (int command, struct zclient
|
Line 160 isis_zebra_if_state_down (int command, struct zclient
|
|
|
static int |
static int |
isis_zebra_if_address_add (int command, struct zclient *zclient, |
isis_zebra_if_address_add (int command, struct zclient *zclient, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
struct connected *c; |
struct connected *c; |
struct prefix *p; |
struct prefix *p; |
char buf[BUFSIZ]; |
char buf[BUFSIZ]; |
|
|
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, |
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, |
zclient->ibuf); | zclient->ibuf, vrf_id); |
|
|
if (c == NULL) |
if (c == NULL) |
return 0; |
return 0; |
Line 187 isis_zebra_if_address_add (int command, struct zclient
|
Line 191 isis_zebra_if_address_add (int command, struct zclient
|
|
|
static int |
static int |
isis_zebra_if_address_del (int command, struct zclient *client, |
isis_zebra_if_address_del (int command, struct zclient *client, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
struct connected *c; |
struct connected *c; |
struct interface *ifp; |
struct interface *ifp; |
Line 197 isis_zebra_if_address_del (int command, struct zclient
|
Line 201 isis_zebra_if_address_del (int command, struct zclient
|
#endif /* EXTREME_DEBUG */ |
#endif /* EXTREME_DEBUG */ |
|
|
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, |
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, |
zclient->ibuf); | zclient->ibuf, vrf_id); |
|
|
if (c == NULL) |
if (c == NULL) |
return 0; |
return 0; |
Line 236 isis_zebra_route_add_ipv4 (struct prefix *prefix,
|
Line 240 isis_zebra_route_add_ipv4 (struct prefix *prefix,
|
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) |
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) |
return; |
return; |
|
|
if (zclient->redist[ZEBRA_ROUTE_ISIS]) | if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT)) |
{ |
{ |
message = 0; |
message = 0; |
flags = 0; |
flags = 0; |
Line 249 isis_zebra_route_add_ipv4 (struct prefix *prefix,
|
Line 253 isis_zebra_route_add_ipv4 (struct prefix *prefix,
|
|
|
stream = zclient->obuf; |
stream = zclient->obuf; |
stream_reset (stream); |
stream_reset (stream); |
zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD); | zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); |
/* type */ |
/* type */ |
stream_putc (stream, ZEBRA_ROUTE_ISIS); |
stream_putc (stream, ZEBRA_ROUTE_ISIS); |
/* flags */ |
/* flags */ |
Line 301 isis_zebra_route_del_ipv4 (struct prefix *prefix,
|
Line 305 isis_zebra_route_del_ipv4 (struct prefix *prefix,
|
struct zapi_ipv4 api; |
struct zapi_ipv4 api; |
struct prefix_ipv4 prefix4; |
struct prefix_ipv4 prefix4; |
|
|
if (zclient->redist[ZEBRA_ROUTE_ISIS]) | if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT)) |
{ |
{ |
|
api.vrf_id = VRF_DEFAULT; |
api.type = ZEBRA_ROUTE_ISIS; |
api.type = ZEBRA_ROUTE_ISIS; |
api.flags = 0; |
api.flags = 0; |
api.message = 0; |
api.message = 0; |
Line 318 isis_zebra_route_del_ipv4 (struct prefix *prefix,
|
Line 323 isis_zebra_route_del_ipv4 (struct prefix *prefix,
|
} |
} |
|
|
#ifdef HAVE_IPV6 |
#ifdef HAVE_IPV6 |
void | static void |
isis_zebra_route_add_ipv6 (struct prefix *prefix, |
isis_zebra_route_add_ipv6 (struct prefix *prefix, |
struct isis_route_info *route_info) |
struct isis_route_info *route_info) |
{ |
{ |
struct zapi_ipv6 api; |
struct zapi_ipv6 api; |
struct in6_addr **nexthop_list; |
struct in6_addr **nexthop_list; |
unsigned int *ifindex_list; | ifindex_t *ifindex_list; |
struct isis_nexthop6 *nexthop6; |
struct isis_nexthop6 *nexthop6; |
int i, size; |
int i, size; |
struct listnode *node; |
struct listnode *node; |
Line 333 isis_zebra_route_add_ipv6 (struct prefix *prefix,
|
Line 338 isis_zebra_route_add_ipv6 (struct prefix *prefix,
|
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) |
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) |
return; |
return; |
|
|
|
api.vrf_id = VRF_DEFAULT; |
api.type = ZEBRA_ROUTE_ISIS; |
api.type = ZEBRA_ROUTE_ISIS; |
api.flags = 0; |
api.flags = 0; |
api.message = 0; |
api.message = 0; |
Line 359 isis_zebra_route_add_ipv6 (struct prefix *prefix,
|
Line 365 isis_zebra_route_add_ipv6 (struct prefix *prefix,
|
|
|
/* allocate memory for ifindex_list */ |
/* allocate memory for ifindex_list */ |
size = sizeof (unsigned int) * listcount (route_info->nexthops6); |
size = sizeof (unsigned int) * listcount (route_info->nexthops6); |
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size); | ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size); |
if (!ifindex_list) |
if (!ifindex_list) |
{ |
{ |
zlog_err ("isis_zebra_add_route_ipv6: out of memory!"); |
zlog_err ("isis_zebra_add_route_ipv6: out of memory!"); |
Line 409 isis_zebra_route_del_ipv6 (struct prefix *prefix,
|
Line 415 isis_zebra_route_del_ipv6 (struct prefix *prefix,
|
{ |
{ |
struct zapi_ipv6 api; |
struct zapi_ipv6 api; |
struct in6_addr **nexthop_list; |
struct in6_addr **nexthop_list; |
unsigned int *ifindex_list; | ifindex_t *ifindex_list; |
struct isis_nexthop6 *nexthop6; |
struct isis_nexthop6 *nexthop6; |
int i, size; |
int i, size; |
struct listnode *node; |
struct listnode *node; |
struct prefix_ipv6 prefix6; |
struct prefix_ipv6 prefix6; |
|
|
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) | if (!CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) |
return; |
return; |
|
|
|
api.vrf_id = VRF_DEFAULT; |
api.type = ZEBRA_ROUTE_ISIS; |
api.type = ZEBRA_ROUTE_ISIS; |
api.flags = 0; |
api.flags = 0; |
api.message = 0; |
api.message = 0; |
Line 438 isis_zebra_route_del_ipv6 (struct prefix *prefix,
|
Line 445 isis_zebra_route_del_ipv6 (struct prefix *prefix,
|
|
|
/* allocate memory for ifindex_list */ |
/* allocate memory for ifindex_list */ |
size = sizeof (unsigned int) * listcount (route_info->nexthops6); |
size = sizeof (unsigned int) * listcount (route_info->nexthops6); |
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size); | ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size); |
if (!ifindex_list) |
if (!ifindex_list) |
{ |
{ |
zlog_err ("isis_zebra_route_del_ipv6: out of memory!"); |
zlog_err ("isis_zebra_route_del_ipv6: out of memory!"); |
Line 488 isis_zebra_route_update (struct prefix *prefix,
|
Line 495 isis_zebra_route_update (struct prefix *prefix,
|
if (zclient->sock < 0) |
if (zclient->sock < 0) |
return; |
return; |
|
|
if (!zclient->redist[ZEBRA_ROUTE_ISIS]) | if (!vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT)) |
return; |
return; |
|
|
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) |
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) |
Line 514 isis_zebra_route_update (struct prefix *prefix,
|
Line 521 isis_zebra_route_update (struct prefix *prefix,
|
|
|
static int |
static int |
isis_zebra_read_ipv4 (int command, struct zclient *zclient, |
isis_zebra_read_ipv4 (int command, struct zclient *zclient, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
struct stream *stream; |
struct stream *stream; |
struct zapi_ipv4 api; |
struct zapi_ipv4 api; |
struct prefix_ipv4 p; |
struct prefix_ipv4 p; |
unsigned long ifindex; | struct prefix *p_generic = (struct prefix*)&p; |
struct in_addr nexthop; | unsigned long ifindex __attribute__ ((unused)); |
| struct in_addr nexthop __attribute__ ((unused)); |
| unsigned char plength = 0; |
|
|
stream = zclient->ibuf; |
stream = zclient->ibuf; |
|
memset(&api, 0, sizeof(api)); |
memset (&p, 0, sizeof (struct prefix_ipv4)); |
memset (&p, 0, sizeof (struct prefix_ipv4)); |
|
memset(&nexthop, 0, sizeof(nexthop)); |
ifindex = 0; |
ifindex = 0; |
|
|
api.type = stream_getc (stream); |
api.type = stream_getc (stream); |
Line 531 isis_zebra_read_ipv4 (int command, struct zclient *zcl
|
Line 542 isis_zebra_read_ipv4 (int command, struct zclient *zcl
|
api.message = stream_getc (stream); |
api.message = stream_getc (stream); |
|
|
p.family = AF_INET; |
p.family = AF_INET; |
p.prefixlen = stream_getc (stream); | plength = stream_getc (stream); |
| p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength); |
stream_get (&p.prefix, stream, PSIZE (p.prefixlen)); |
stream_get (&p.prefix, stream, PSIZE (p.prefixlen)); |
|
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) |
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) |
Line 548 isis_zebra_read_ipv4 (int command, struct zclient *zcl
|
Line 560 isis_zebra_read_ipv4 (int command, struct zclient *zcl
|
api.distance = stream_getc (stream); |
api.distance = stream_getc (stream); |
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) |
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) |
api.metric = stream_getl (stream); |
api.metric = stream_getl (stream); |
else |
|
api.metric = 0; |
|
|
|
|
/* |
|
* 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) |
|
*/ |
|
if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) |
|
command = ZEBRA_IPV4_ROUTE_DELETE; |
|
|
if (command == ZEBRA_IPV4_ROUTE_ADD) |
if (command == ZEBRA_IPV4_ROUTE_ADD) |
{ | isis_redist_add(api.type, p_generic, api.distance, api.metric); |
if (isis->debugs & DEBUG_ZEBRA) | else |
zlog_debug ("IPv4 Route add from Z"); | isis_redist_delete(api.type, p_generic); |
} | |
|
|
return 0; |
return 0; |
} |
} |
|
|
#ifdef HAVE_IPV6 |
|
static int |
static int |
isis_zebra_read_ipv6 (int command, struct zclient *zclient, |
isis_zebra_read_ipv6 (int command, struct zclient *zclient, |
zebra_size_t length) | zebra_size_t length, vrf_id_t vrf_id) |
{ |
{ |
|
struct stream *stream; |
|
struct zapi_ipv6 api; |
|
struct prefix_ipv6 p; |
|
struct prefix *p_generic = (struct prefix*)&p; |
|
struct in6_addr nexthop; |
|
unsigned long ifindex __attribute__((unused)); |
|
|
|
stream = zclient->ibuf; |
|
memset(&api, 0, sizeof(api)); |
|
memset(&p, 0, sizeof(struct prefix_ipv6)); |
|
memset(&nexthop, 0, sizeof(nexthop)); |
|
ifindex = 0; |
|
|
|
api.type = stream_getc(stream); |
|
api.flags = stream_getc(stream); |
|
api.message = stream_getc(stream); |
|
|
|
p.family = AF_INET6; |
|
p.prefixlen = stream_getc(stream); |
|
stream_get(&p.prefix, stream, PSIZE(p.prefixlen)); |
|
|
|
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) |
|
{ |
|
api.nexthop_num = stream_getc(stream); /* this is always 1 */ |
|
stream_get(&nexthop, stream, sizeof(nexthop)); |
|
} |
|
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) |
|
{ |
|
api.ifindex_num = stream_getc(stream); |
|
ifindex = stream_getl(stream); |
|
} |
|
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) |
|
api.distance = stream_getc(stream); |
|
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) |
|
api.metric = stream_getl(stream); |
|
|
|
/* |
|
* 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) |
|
*/ |
|
if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS) |
|
command = ZEBRA_IPV6_ROUTE_DELETE; |
|
|
|
if (command == ZEBRA_IPV6_ROUTE_ADD) |
|
isis_redist_add(api.type, p_generic, api.distance, api.metric); |
|
else |
|
isis_redist_delete(api.type, p_generic); |
|
|
return 0; |
return 0; |
} |
} |
#endif |
|
|
|
#define ISIS_TYPE_IS_REDISTRIBUTED(T) \ |
|
T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type] |
|
|
|
int |
int |
isis_distribute_list_update (int routetype) |
isis_distribute_list_update (int routetype) |
{ |
{ |
return 0; |
return 0; |
} |
} |
|
|
#if 0 /* Not yet. */ | void |
static int | isis_zebra_redistribute_set(int type) |
isis_redistribute_default_set (int routetype, int metric_type, | |
int metric_value) | |
{ |
{ |
return 0; | if (type == DEFAULT_ROUTE) |
| zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, VRF_DEFAULT); |
| else |
| zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT); |
} |
} |
#endif /* 0 */ |
|
|
|
void |
void |
isis_zebra_init () | isis_zebra_redistribute_unset(int type) |
{ |
{ |
zclient = zclient_new (); | if (type == DEFAULT_ROUTE) |
| zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, VRF_DEFAULT); |
| else |
| zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, type, VRF_DEFAULT); |
| } |
| |
| static void |
| isis_zebra_connected (struct zclient *zclient) |
| { |
| zclient_send_requests (zclient, VRF_DEFAULT); |
| } |
| |
| void |
| isis_zebra_init (struct thread_master *master) |
| { |
| zclient = zclient_new (master); |
zclient_init (zclient, ZEBRA_ROUTE_ISIS); |
zclient_init (zclient, ZEBRA_ROUTE_ISIS); |
|
zclient->zebra_connected = isis_zebra_connected; |
zclient->router_id_update = isis_router_id_update_zebra; |
zclient->router_id_update = isis_router_id_update_zebra; |
zclient->interface_add = isis_zebra_if_add; |
zclient->interface_add = isis_zebra_if_add; |
zclient->interface_delete = isis_zebra_if_del; |
zclient->interface_delete = isis_zebra_if_del; |