version 1.1.1.3, 2013/07/21 23:54:39
|
version 1.1.1.4, 2016/11/02 10:09:10
|
Line 32
|
Line 32
|
#include "zclient.h" |
#include "zclient.h" |
#include "memory.h" |
#include "memory.h" |
#include "table.h" |
#include "table.h" |
| |
/* Zebra client events. */ |
/* Zebra client events. */ |
enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT}; |
enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT}; |
|
|
/* Prototype for event manager. */ |
/* Prototype for event manager. */ |
static void zclient_event (enum event, struct zclient *); |
static void zclient_event (enum event, struct zclient *); |
|
|
extern struct thread_master *master; | const char *zclient_serv_path = NULL; |
|
|
char *zclient_serv_path = NULL; |
|
|
|
/* This file local debug flag. */ |
/* This file local debug flag. */ |
int zclient_debug = 0; |
int zclient_debug = 0; |
| |
/* Allocate zclient structure. */ |
/* Allocate zclient structure. */ |
struct zclient * |
struct zclient * |
zclient_new () | zclient_new (struct thread_master *master) |
{ |
{ |
struct zclient *zclient; |
struct zclient *zclient; |
zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient)); |
zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient)); |
Line 56 zclient_new ()
|
Line 54 zclient_new ()
|
zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ); |
zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ); |
zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ); |
zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ); |
zclient->wb = buffer_new(0); |
zclient->wb = buffer_new(0); |
|
zclient->master = master; |
|
|
return zclient; |
return zclient; |
} |
} |
Line 93 zclient_init (struct zclient *zclient, int redist_defa
|
Line 92 zclient_init (struct zclient *zclient, int redist_defa
|
|
|
/* Clear redistribution flags. */ |
/* Clear redistribution flags. */ |
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) |
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) |
zclient->redist[i] = 0; | zclient->redist[i] = vrf_bitmap_init (); |
|
|
/* Set unwanted redistribute route. bgpd does not need BGP route |
/* Set unwanted redistribute route. bgpd does not need BGP route |
redistribution. */ |
redistribution. */ |
zclient->redist_default = redist_default; |
zclient->redist_default = redist_default; |
zclient->redist[redist_default] = 1; |
|
|
|
/* Set default-information redistribute to zero. */ |
/* Set default-information redistribute to zero. */ |
zclient->default_information = 0; | zclient->default_information = vrf_bitmap_init (); |
|
|
/* Schedule first zclient connection. */ |
/* Schedule first zclient connection. */ |
if (zclient_debug) |
if (zclient_debug) |
Line 114 zclient_init (struct zclient *zclient, int redist_defa
|
Line 112 zclient_init (struct zclient *zclient, int redist_defa
|
void |
void |
zclient_stop (struct zclient *zclient) |
zclient_stop (struct zclient *zclient) |
{ |
{ |
|
int i; |
|
|
if (zclient_debug) |
if (zclient_debug) |
zlog_debug ("zclient stopped"); |
zlog_debug ("zclient stopped"); |
|
|
Line 136 zclient_stop (struct zclient *zclient)
|
Line 136 zclient_stop (struct zclient *zclient)
|
zclient->sock = -1; |
zclient->sock = -1; |
} |
} |
zclient->fail = 0; |
zclient->fail = 0; |
|
|
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) |
|
{ |
|
vrf_bitmap_free(zclient->redist[i]); |
|
zclient->redist[i] = VRF_BITMAP_NULL; |
|
} |
|
vrf_bitmap_free(zclient->default_information); |
|
zclient->default_information = VRF_BITMAP_NULL; |
} |
} |
|
|
void |
void |
Line 229 zclient_socket_connect (struct zclient *zclient)
|
Line 237 zclient_socket_connect (struct zclient *zclient)
|
#ifdef HAVE_TCP_ZEBRA |
#ifdef HAVE_TCP_ZEBRA |
zclient->sock = zclient_socket (); |
zclient->sock = zclient_socket (); |
#else |
#else |
zclient->sock = zclient_socket_un (zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH); | zclient->sock = zclient_socket_un (zclient_serv_path_get()); |
#endif |
#endif |
return zclient->sock; |
return zclient->sock; |
} |
} |
Line 259 zclient_flush_data(struct thread *thread)
|
Line 267 zclient_flush_data(struct thread *thread)
|
return zclient_failed(zclient); |
return zclient_failed(zclient); |
break; |
break; |
case BUFFER_PENDING: |
case BUFFER_PENDING: |
zclient->t_write = thread_add_write(master, zclient_flush_data, | zclient->t_write = thread_add_write (zclient->master, zclient_flush_data, |
zclient, zclient->sock); | zclient, zclient->sock); |
break; |
break; |
case BUFFER_EMPTY: |
case BUFFER_EMPTY: |
break; |
break; |
Line 285 zclient_send_message(struct zclient *zclient)
|
Line 293 zclient_send_message(struct zclient *zclient)
|
THREAD_OFF(zclient->t_write); |
THREAD_OFF(zclient->t_write); |
break; |
break; |
case BUFFER_PENDING: |
case BUFFER_PENDING: |
THREAD_WRITE_ON(master, zclient->t_write, | THREAD_WRITE_ON (zclient->master, zclient->t_write, |
zclient_flush_data, zclient, zclient->sock); | zclient_flush_data, zclient, zclient->sock); |
break; |
break; |
} |
} |
return 0; |
return 0; |
} |
} |
|
|
void |
void |
zclient_create_header (struct stream *s, uint16_t command) | zclient_create_header (struct stream *s, uint16_t command, vrf_id_t vrf_id) |
{ |
{ |
/* length placeholder, caller can update */ |
/* length placeholder, caller can update */ |
stream_putw (s, ZEBRA_HEADER_SIZE); |
stream_putw (s, ZEBRA_HEADER_SIZE); |
stream_putc (s, ZEBRA_HEADER_MARKER); |
stream_putc (s, ZEBRA_HEADER_MARKER); |
stream_putc (s, ZSERV_VERSION); |
stream_putc (s, ZSERV_VERSION); |
|
stream_putw (s, vrf_id); |
stream_putw (s, command); |
stream_putw (s, command); |
} |
} |
|
|
|
int |
|
zclient_read_header (struct stream *s, int sock, u_int16_t *size, u_char *marker, |
|
u_char *version, u_int16_t *vrf_id, u_int16_t *cmd) |
|
{ |
|
if (stream_read (s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE) |
|
return -1; |
|
|
|
*size = stream_getw (s) - ZEBRA_HEADER_SIZE; |
|
*marker = stream_getc (s); |
|
*version = stream_getc (s); |
|
*vrf_id = stream_getw (s); |
|
*cmd = stream_getw (s); |
|
|
|
if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) |
|
{ |
|
zlog_err("%s: socket %d version mismatch, marker %d, version %d", |
|
__func__, sock, *marker, *version); |
|
return -1; |
|
} |
|
|
|
if (*size && stream_read (s, sock, *size) != *size) |
|
return -1; |
|
|
|
return 0; |
|
} |
|
|
/* Send simple Zebra message. */ |
/* Send simple Zebra message. */ |
static int |
static int |
zebra_message_send (struct zclient *zclient, int command) | zebra_message_send (struct zclient *zclient, int command, vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
|
|
Line 313 zebra_message_send (struct zclient *zclient, int comma
|
Line 348 zebra_message_send (struct zclient *zclient, int comma
|
stream_reset (s); |
stream_reset (s); |
|
|
/* Send very simple command only Zebra message. */ |
/* Send very simple command only Zebra message. */ |
zclient_create_header (s, command); | zclient_create_header (s, command, vrf_id); |
|
|
return zclient_send_message(zclient); |
return zclient_send_message(zclient); |
} |
} |
Line 328 zebra_hello_send (struct zclient *zclient)
|
Line 363 zebra_hello_send (struct zclient *zclient)
|
s = zclient->obuf; |
s = zclient->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
zclient_create_header (s, ZEBRA_HELLO); | /* The VRF ID in the HELLO message is always 0. */ |
| zclient_create_header (s, ZEBRA_HELLO, VRF_DEFAULT); |
stream_putc (s, zclient->redist_default); |
stream_putc (s, zclient->redist_default); |
stream_putw_at (s, 0, stream_get_endp (s)); |
stream_putw_at (s, 0, stream_get_endp (s)); |
return zclient_send_message(zclient); |
return zclient_send_message(zclient); |
Line 337 zebra_hello_send (struct zclient *zclient)
|
Line 373 zebra_hello_send (struct zclient *zclient)
|
return 0; |
return 0; |
} |
} |
|
|
|
/* Send requests to zebra daemon for the information in a VRF. */ |
|
void |
|
zclient_send_requests (struct zclient *zclient, vrf_id_t vrf_id) |
|
{ |
|
int i; |
|
|
|
/* zclient is disabled. */ |
|
if (! zclient->enable) |
|
return; |
|
|
|
/* If not connected to the zebra yet. */ |
|
if (zclient->sock < 0) |
|
return; |
|
|
|
if (zclient_debug) |
|
zlog_debug ("%s: send messages for VRF %u", __func__, vrf_id); |
|
|
|
/* We need router-id information. */ |
|
zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD, vrf_id); |
|
|
|
/* We need interface information. */ |
|
zebra_message_send (zclient, ZEBRA_INTERFACE_ADD, vrf_id); |
|
|
|
/* Set unwanted redistribute route. */ |
|
vrf_bitmap_set (zclient->redist[zclient->redist_default], vrf_id); |
|
|
|
/* Flush all redistribute request. */ |
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) |
|
if (i != zclient->redist_default && |
|
vrf_bitmap_check (zclient->redist[i], vrf_id)) |
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i, vrf_id); |
|
|
|
/* If default information is needed. */ |
|
if (vrf_bitmap_check (zclient->default_information, VRF_DEFAULT)) |
|
zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD, vrf_id); |
|
} |
|
|
/* Make connection to zebra daemon. */ |
/* Make connection to zebra daemon. */ |
int |
int |
zclient_start (struct zclient *zclient) |
zclient_start (struct zclient *zclient) |
{ |
{ |
int i; |
|
|
|
if (zclient_debug) |
if (zclient_debug) |
zlog_debug ("zclient_start is called"); |
zlog_debug ("zclient_start is called"); |
|
|
Line 380 zclient_start (struct zclient *zclient)
|
Line 451 zclient_start (struct zclient *zclient)
|
|
|
zebra_hello_send (zclient); |
zebra_hello_send (zclient); |
|
|
/* We need router-id information. */ | /* Inform the successful connection. */ |
zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD); | if (zclient->zebra_connected) |
| (*zclient->zebra_connected) (zclient); |
|
|
/* We need interface information. */ |
|
zebra_message_send (zclient, ZEBRA_INTERFACE_ADD); |
|
|
|
/* Flush all redistribute request. */ |
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) |
|
if (i != zclient->redist_default && zclient->redist[i]) |
|
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, i); |
|
|
|
/* If default information is needed. */ |
|
if (zclient->default_information) |
|
zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD); |
|
|
|
return 0; |
return 0; |
} |
} |
|
|
Line 413 zclient_connect (struct thread *t)
|
Line 473 zclient_connect (struct thread *t)
|
|
|
return zclient_start (zclient); |
return zclient_start (zclient); |
} |
} |
| |
/* |
/* |
* "xdr_encode"-like interface that allows daemon (client) to send |
* "xdr_encode"-like interface that allows daemon (client) to send |
* a message to zebra server for a route that needs to be |
* a message to zebra server for a route that needs to be |
Line 469 zapi_ipv4_route (u_char cmd, struct zclient *zclient,
|
Line 529 zapi_ipv4_route (u_char cmd, struct zclient *zclient,
|
/* Reset stream. */ |
/* Reset stream. */ |
s = zclient->obuf; |
s = zclient->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
|
zclient_create_header (s, cmd, api->vrf_id); |
|
|
zclient_create_header (s, cmd); |
|
|
|
/* Put type and nexthop. */ |
/* Put type and nexthop. */ |
stream_putc (s, api->type); |
stream_putc (s, api->type); |
stream_putc (s, api->flags); |
stream_putc (s, api->flags); |
Line 512 zapi_ipv4_route (u_char cmd, struct zclient *zclient,
|
Line 572 zapi_ipv4_route (u_char cmd, struct zclient *zclient,
|
stream_putc (s, api->distance); |
stream_putc (s, api->distance); |
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) |
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) |
stream_putl (s, api->metric); |
stream_putl (s, api->metric); |
|
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU)) |
|
stream_putl (s, api->mtu); |
|
|
/* Put length at the first point of the stream. */ |
/* Put length at the first point of the stream. */ |
stream_putw_at (s, 0, stream_get_endp (s)); |
stream_putw_at (s, 0, stream_get_endp (s)); |
Line 532 zapi_ipv6_route (u_char cmd, struct zclient *zclient,
|
Line 594 zapi_ipv6_route (u_char cmd, struct zclient *zclient,
|
s = zclient->obuf; |
s = zclient->obuf; |
stream_reset (s); |
stream_reset (s); |
|
|
zclient_create_header (s, cmd); | zclient_create_header (s, cmd, api->vrf_id); |
|
|
/* Put type and nexthop. */ |
/* Put type and nexthop. */ |
stream_putc (s, api->type); |
stream_putc (s, api->type); |
Line 566 zapi_ipv6_route (u_char cmd, struct zclient *zclient,
|
Line 628 zapi_ipv6_route (u_char cmd, struct zclient *zclient,
|
stream_putc (s, api->distance); |
stream_putc (s, api->distance); |
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) |
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) |
stream_putl (s, api->metric); |
stream_putl (s, api->metric); |
|
if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU)) |
|
stream_putl (s, api->mtu); |
|
|
/* Put length at the first point of the stream. */ |
/* Put length at the first point of the stream. */ |
stream_putw_at (s, 0, stream_get_endp (s)); |
stream_putw_at (s, 0, stream_get_endp (s)); |
Line 581 zapi_ipv6_route (u_char cmd, struct zclient *zclient,
|
Line 645 zapi_ipv6_route (u_char cmd, struct zclient *zclient,
|
* sending client |
* sending client |
*/ |
*/ |
int |
int |
zebra_redistribute_send (int command, struct zclient *zclient, int type) | zebra_redistribute_send (int command, struct zclient *zclient, int type, |
| vrf_id_t vrf_id) |
{ |
{ |
struct stream *s; |
struct stream *s; |
|
|
s = zclient->obuf; |
s = zclient->obuf; |
stream_reset(s); |
stream_reset(s); |
|
|
zclient_create_header (s, command); | zclient_create_header (s, command, vrf_id); |
stream_putc (s, type); |
stream_putc (s, type); |
|
|
stream_putw_at (s, 0, stream_get_endp (s)); |
stream_putw_at (s, 0, stream_get_endp (s)); |
Line 596 zebra_redistribute_send (int command, struct zclient *
|
Line 661 zebra_redistribute_send (int command, struct zclient *
|
return zclient_send_message(zclient); |
return zclient_send_message(zclient); |
} |
} |
|
|
|
/* Get prefix in ZServ format; family should be filled in on prefix */ |
|
static void |
|
zclient_stream_get_prefix (struct stream *s, struct prefix *p) |
|
{ |
|
size_t plen = prefix_blen (p); |
|
u_char c; |
|
p->prefixlen = 0; |
|
|
|
if (plen == 0) |
|
return; |
|
|
|
stream_get (&p->u.prefix, s, plen); |
|
c = stream_getc(s); |
|
p->prefixlen = MIN(plen * 8, c); |
|
} |
|
|
/* Router-id update from zebra daemon. */ |
/* Router-id update from zebra daemon. */ |
void |
void |
zebra_router_id_update_read (struct stream *s, struct prefix *rid) |
zebra_router_id_update_read (struct stream *s, struct prefix *rid) |
{ |
{ |
int plen; |
|
|
|
/* Fetch interface address. */ |
/* Fetch interface address. */ |
rid->family = stream_getc (s); |
rid->family = stream_getc (s); |
| |
plen = prefix_blen (rid); | zclient_stream_get_prefix (s, rid); |
stream_get (&rid->u.prefix, s, plen); | |
rid->prefixlen = stream_getc (s); | |
} |
} |
|
|
/* Interface addition from zebra daemon. */ |
/* Interface addition from zebra daemon. */ |
Line 643 zebra_router_id_update_read (struct stream *s, struct
|
Line 720 zebra_router_id_update_read (struct stream *s, struct
|
*/ |
*/ |
|
|
struct interface * |
struct interface * |
zebra_interface_add_read (struct stream *s) | zebra_interface_add_read (struct stream *s, vrf_id_t vrf_id) |
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
char ifname_tmp[INTERFACE_NAMSIZ]; |
char ifname_tmp[INTERFACE_NAMSIZ]; |
Line 652 zebra_interface_add_read (struct stream *s)
|
Line 729 zebra_interface_add_read (struct stream *s)
|
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); |
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); |
|
|
/* Lookup/create interface by name. */ |
/* Lookup/create interface by name. */ |
ifp = if_get_by_name_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ)); | ifp = if_get_by_name_len_vrf (ifname_tmp, |
| strnlen (ifname_tmp, INTERFACE_NAMSIZ), |
| vrf_id); |
|
|
zebra_interface_if_set_value (s, ifp); |
zebra_interface_if_set_value (s, ifp); |
|
|
Line 667 zebra_interface_add_read (struct stream *s)
|
Line 746 zebra_interface_add_read (struct stream *s)
|
* is sent at the tail of the message. |
* is sent at the tail of the message. |
*/ |
*/ |
struct interface * |
struct interface * |
zebra_interface_state_read (struct stream *s) | zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id) |
{ |
{ |
struct interface *ifp; |
struct interface *ifp; |
char ifname_tmp[INTERFACE_NAMSIZ]; |
char ifname_tmp[INTERFACE_NAMSIZ]; |
Line 676 zebra_interface_state_read (struct stream *s)
|
Line 755 zebra_interface_state_read (struct stream *s)
|
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); |
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); |
|
|
/* Lookup this by interface index. */ |
/* Lookup this by interface index. */ |
ifp = if_lookup_by_name_len (ifname_tmp, | ifp = if_lookup_by_name_len_vrf (ifname_tmp, |
strnlen(ifname_tmp, INTERFACE_NAMSIZ)); | strnlen (ifname_tmp, INTERFACE_NAMSIZ), |
| vrf_id); |
|
|
/* If such interface does not exist, indicate an error */ |
/* If such interface does not exist, indicate an error */ |
if (! ifp) |
if (! ifp) |
Line 733 zebra_interface_if_set_value (struct stream *s, struct
|
Line 813 zebra_interface_if_set_value (struct stream *s, struct
|
ifp->mtu = stream_getl (s); |
ifp->mtu = stream_getl (s); |
ifp->mtu6 = stream_getl (s); |
ifp->mtu6 = stream_getl (s); |
ifp->bandwidth = stream_getl (s); |
ifp->bandwidth = stream_getl (s); |
#ifdef HAVE_STRUCT_SOCKADDR_DL | ifp->ll_type = stream_getl (s); |
stream_get (&ifp->sdl, s, sizeof (ifp->sdl_storage)); | |
#else | |
ifp->hw_addr_len = stream_getl (s); |
ifp->hw_addr_len = stream_getl (s); |
if (ifp->hw_addr_len) |
if (ifp->hw_addr_len) |
stream_get (ifp->hw_addr, s, ifp->hw_addr_len); | stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX)); |
#endif /* HAVE_STRUCT_SOCKADDR_DL */ | |
} |
} |
|
|
static int |
static int |
Line 754 memconstant(const void *s, int c, size_t n)
|
Line 831 memconstant(const void *s, int c, size_t n)
|
} |
} |
|
|
struct connected * |
struct connected * |
zebra_interface_address_read (int type, struct stream *s) | zebra_interface_address_read (int type, struct stream *s, vrf_id_t vrf_id) |
{ |
{ |
unsigned int ifindex; | ifindex_t ifindex; |
struct interface *ifp; |
struct interface *ifp; |
struct connected *ifc; |
struct connected *ifc; |
struct prefix p, d; | struct prefix p, d, *dp; |
int family; | |
int plen; |
int plen; |
u_char ifc_flags; |
u_char ifc_flags; |
|
|
Line 771 zebra_interface_address_read (int type, struct stream
|
Line 847 zebra_interface_address_read (int type, struct stream
|
ifindex = stream_getl (s); |
ifindex = stream_getl (s); |
|
|
/* Lookup index. */ |
/* Lookup index. */ |
ifp = if_lookup_by_index (ifindex); | ifp = if_lookup_by_index_vrf (ifindex, vrf_id); |
if (ifp == NULL) |
if (ifp == NULL) |
{ |
{ |
zlog_warn ("zebra_interface_address_read(%s): " |
zlog_warn ("zebra_interface_address_read(%s): " |
Line 785 zebra_interface_address_read (int type, struct stream
|
Line 861 zebra_interface_address_read (int type, struct stream
|
ifc_flags = stream_getc (s); |
ifc_flags = stream_getc (s); |
|
|
/* Fetch interface address. */ |
/* Fetch interface address. */ |
family = p.family = stream_getc (s); | d.family = p.family = stream_getc (s); |
| plen = prefix_blen (&d); |
| |
| zclient_stream_get_prefix (s, &p); |
|
|
plen = prefix_blen (&p); |
|
stream_get (&p.u.prefix, s, plen); |
|
p.prefixlen = stream_getc (s); |
|
|
|
/* Fetch destination address. */ |
/* Fetch destination address. */ |
stream_get (&d.u.prefix, s, plen); |
stream_get (&d.u.prefix, s, plen); |
d.family = family; | |
| /* N.B. NULL destination pointers are encoded as all zeroes */ |
| dp = memconstant(&d.u.prefix,0,plen) ? NULL : &d; |
| |
if (type == ZEBRA_INTERFACE_ADDRESS_ADD) |
if (type == ZEBRA_INTERFACE_ADDRESS_ADD) |
{ |
{ |
/* N.B. NULL destination pointers are encoded as all zeroes */ |
/* N.B. NULL destination pointers are encoded as all zeroes */ |
ifc = connected_add_by_prefix(ifp, &p,(memconstant(&d.u.prefix,0,plen) ? | ifc = connected_add_by_prefix(ifp, &p, dp); |
NULL : &d)); | |
if (ifc != NULL) |
if (ifc != NULL) |
{ |
{ |
ifc->flags = ifc_flags; |
ifc->flags = ifc_flags; |
if (ifc->destination) |
if (ifc->destination) |
ifc->destination->prefixlen = ifc->address->prefixlen; |
ifc->destination->prefixlen = ifc->address->prefixlen; |
|
else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) |
|
{ |
|
/* carp interfaces on OpenBSD with 0.0.0.0/0 as "peer" */ |
|
char buf[PREFIX_STRLEN]; |
|
zlog_warn("warning: interface %s address %s " |
|
"with peer flag set, but no peer address!", |
|
ifp->name, |
|
prefix2str (ifc->address, buf, sizeof buf)); |
|
UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); |
|
} |
} |
} |
} |
} |
else |
else |
Line 816 zebra_interface_address_read (int type, struct stream
|
Line 902 zebra_interface_address_read (int type, struct stream
|
return ifc; |
return ifc; |
} |
} |
|
|
| |
/* Zebra client message read function. */ |
/* Zebra client message read function. */ |
static int |
static int |
zclient_read (struct thread *thread) |
zclient_read (struct thread *thread) |
Line 824 zclient_read (struct thread *thread)
|
Line 910 zclient_read (struct thread *thread)
|
size_t already; |
size_t already; |
uint16_t length, command; |
uint16_t length, command; |
uint8_t marker, version; |
uint8_t marker, version; |
|
vrf_id_t vrf_id; |
struct zclient *zclient; |
struct zclient *zclient; |
|
|
/* Get socket to zebra. */ |
/* Get socket to zebra. */ |
Line 858 zclient_read (struct thread *thread)
|
Line 945 zclient_read (struct thread *thread)
|
length = stream_getw (zclient->ibuf); |
length = stream_getw (zclient->ibuf); |
marker = stream_getc (zclient->ibuf); |
marker = stream_getc (zclient->ibuf); |
version = stream_getc (zclient->ibuf); |
version = stream_getc (zclient->ibuf); |
|
vrf_id = stream_getw (zclient->ibuf); |
command = stream_getw (zclient->ibuf); |
command = stream_getw (zclient->ibuf); |
|
|
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) |
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) |
Line 909 zclient_read (struct thread *thread)
|
Line 997 zclient_read (struct thread *thread)
|
length -= ZEBRA_HEADER_SIZE; |
length -= ZEBRA_HEADER_SIZE; |
|
|
if (zclient_debug) |
if (zclient_debug) |
zlog_debug("zclient 0x%p command 0x%x \n", zclient, command); | zlog_debug("zclient 0x%p command 0x%x VRF %u\n", (void *)zclient, command, vrf_id); |
|
|
switch (command) |
switch (command) |
{ |
{ |
case ZEBRA_ROUTER_ID_UPDATE: |
case ZEBRA_ROUTER_ID_UPDATE: |
if (zclient->router_id_update) |
if (zclient->router_id_update) |
(*zclient->router_id_update) (command, zclient, length); | (*zclient->router_id_update) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_INTERFACE_ADD: |
case ZEBRA_INTERFACE_ADD: |
if (zclient->interface_add) |
if (zclient->interface_add) |
(*zclient->interface_add) (command, zclient, length); | (*zclient->interface_add) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_INTERFACE_DELETE: |
case ZEBRA_INTERFACE_DELETE: |
if (zclient->interface_delete) |
if (zclient->interface_delete) |
(*zclient->interface_delete) (command, zclient, length); | (*zclient->interface_delete) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_INTERFACE_ADDRESS_ADD: |
case ZEBRA_INTERFACE_ADDRESS_ADD: |
if (zclient->interface_address_add) |
if (zclient->interface_address_add) |
(*zclient->interface_address_add) (command, zclient, length); | (*zclient->interface_address_add) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_INTERFACE_ADDRESS_DELETE: |
case ZEBRA_INTERFACE_ADDRESS_DELETE: |
if (zclient->interface_address_delete) |
if (zclient->interface_address_delete) |
(*zclient->interface_address_delete) (command, zclient, length); | (*zclient->interface_address_delete) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_INTERFACE_UP: |
case ZEBRA_INTERFACE_UP: |
if (zclient->interface_up) |
if (zclient->interface_up) |
(*zclient->interface_up) (command, zclient, length); | (*zclient->interface_up) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_INTERFACE_DOWN: |
case ZEBRA_INTERFACE_DOWN: |
if (zclient->interface_down) |
if (zclient->interface_down) |
(*zclient->interface_down) (command, zclient, length); | (*zclient->interface_down) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_IPV4_ROUTE_ADD: |
case ZEBRA_IPV4_ROUTE_ADD: |
if (zclient->ipv4_route_add) |
if (zclient->ipv4_route_add) |
(*zclient->ipv4_route_add) (command, zclient, length); | (*zclient->ipv4_route_add) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_IPV4_ROUTE_DELETE: |
case ZEBRA_IPV4_ROUTE_DELETE: |
if (zclient->ipv4_route_delete) |
if (zclient->ipv4_route_delete) |
(*zclient->ipv4_route_delete) (command, zclient, length); | (*zclient->ipv4_route_delete) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_IPV6_ROUTE_ADD: |
case ZEBRA_IPV6_ROUTE_ADD: |
if (zclient->ipv6_route_add) |
if (zclient->ipv6_route_add) |
(*zclient->ipv6_route_add) (command, zclient, length); | (*zclient->ipv6_route_add) (command, zclient, length, vrf_id); |
break; |
break; |
case ZEBRA_IPV6_ROUTE_DELETE: |
case ZEBRA_IPV6_ROUTE_DELETE: |
if (zclient->ipv6_route_delete) |
if (zclient->ipv6_route_delete) |
(*zclient->ipv6_route_delete) (command, zclient, length); | (*zclient->ipv6_route_delete) (command, zclient, length, vrf_id); |
break; |
break; |
default: |
default: |
break; |
break; |
Line 973 zclient_read (struct thread *thread)
|
Line 1061 zclient_read (struct thread *thread)
|
} |
} |
|
|
void |
void |
zclient_redistribute (int command, struct zclient *zclient, int type) | zclient_redistribute (int command, struct zclient *zclient, int type, |
| vrf_id_t vrf_id) |
{ |
{ |
|
|
if (command == ZEBRA_REDISTRIBUTE_ADD) |
if (command == ZEBRA_REDISTRIBUTE_ADD) |
{ |
{ |
if (zclient->redist[type]) | if (vrf_bitmap_check (zclient->redist[type], vrf_id)) |
return; |
return; |
zclient->redist[type] = 1; | vrf_bitmap_set (zclient->redist[type], vrf_id); |
} |
} |
else |
else |
{ |
{ |
if (!zclient->redist[type]) | if (!vrf_bitmap_check (zclient->redist[type], vrf_id)) |
return; |
return; |
zclient->redist[type] = 0; | vrf_bitmap_unset (zclient->redist[type], vrf_id); |
} |
} |
|
|
if (zclient->sock > 0) |
if (zclient->sock > 0) |
zebra_redistribute_send (command, zclient, type); | zebra_redistribute_send (command, zclient, type, vrf_id); |
} |
} |
|
|
|
|
void |
void |
zclient_redistribute_default (int command, struct zclient *zclient) | zclient_redistribute_default (int command, struct zclient *zclient, |
| vrf_id_t vrf_id) |
{ |
{ |
|
|
if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) |
if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) |
{ |
{ |
if (zclient->default_information) | if (vrf_bitmap_check (zclient->default_information, vrf_id)) |
return; |
return; |
zclient->default_information = 1; | vrf_bitmap_set (zclient->default_information, vrf_id); |
} |
} |
else |
else |
{ |
{ |
if (!zclient->default_information) | if (!vrf_bitmap_check (zclient->default_information, vrf_id)) |
return; |
return; |
zclient->default_information = 0; | vrf_bitmap_unset (zclient->default_information, vrf_id); |
} |
} |
|
|
if (zclient->sock > 0) |
if (zclient->sock > 0) |
zebra_message_send (zclient, command); | zebra_message_send (zclient, command, vrf_id); |
} |
} |
|
|
static void |
static void |
Line 1023 zclient_event (enum event event, struct zclient *zclie
|
Line 1113 zclient_event (enum event event, struct zclient *zclie
|
case ZCLIENT_SCHEDULE: |
case ZCLIENT_SCHEDULE: |
if (! zclient->t_connect) |
if (! zclient->t_connect) |
zclient->t_connect = |
zclient->t_connect = |
thread_add_event (master, zclient_connect, zclient, 0); | thread_add_event (zclient->master, zclient_connect, zclient, 0); |
break; |
break; |
case ZCLIENT_CONNECT: |
case ZCLIENT_CONNECT: |
if (zclient->fail >= 10) |
if (zclient->fail >= 10) |
Line 1033 zclient_event (enum event event, struct zclient *zclie
|
Line 1123 zclient_event (enum event event, struct zclient *zclie
|
zclient->fail < 3 ? 10 : 60); |
zclient->fail < 3 ? 10 : 60); |
if (! zclient->t_connect) |
if (! zclient->t_connect) |
zclient->t_connect = |
zclient->t_connect = |
thread_add_timer (master, zclient_connect, zclient, | thread_add_timer (zclient->master, zclient_connect, zclient, |
zclient->fail < 3 ? 10 : 60); |
zclient->fail < 3 ? 10 : 60); |
break; |
break; |
case ZCLIENT_READ: |
case ZCLIENT_READ: |
zclient->t_read = |
zclient->t_read = |
thread_add_read (master, zclient_read, zclient, zclient->sock); | thread_add_read (zclient->master, zclient_read, zclient, zclient->sock); |
break; |
break; |
} |
} |
|
} |
|
|
|
const char *zclient_serv_path_get() |
|
{ |
|
return zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH; |
} |
} |
|
|
void |
void |