version 1.1.1.1, 2012/02/21 17:26:12
|
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; |
|
|
/* 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 54 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 91 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 112 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 134 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 143 zclient_reset (struct zclient *zclient)
|
Line 153 zclient_reset (struct zclient *zclient)
|
zclient_init (zclient, zclient->redist_default); |
zclient_init (zclient, zclient->redist_default); |
} |
} |
|
|
|
#ifdef HAVE_TCP_ZEBRA |
|
|
/* Make socket to zebra daemon. Return zebra socket. */ |
/* Make socket to zebra daemon. Return zebra socket. */ |
int | static int |
zclient_socket(void) |
zclient_socket(void) |
{ |
{ |
int sock; |
int sock; |
Line 175 zclient_socket(void)
|
Line 187 zclient_socket(void)
|
return sock; |
return sock; |
} |
} |
|
|
|
#else |
|
|
/* For sockaddr_un. */ |
/* For sockaddr_un. */ |
#include <sys/un.h> |
#include <sys/un.h> |
|
|
int | static int |
zclient_socket_un (const char *path) |
zclient_socket_un (const char *path) |
{ |
{ |
int ret; |
int ret; |
Line 208 zclient_socket_un (const char *path)
|
Line 222 zclient_socket_un (const char *path)
|
return sock; |
return sock; |
} |
} |
|
|
|
#endif /* HAVE_TCP_ZEBRA */ |
|
|
|
/** |
|
* Connect to zebra daemon. |
|
* @param zclient a pointer to zclient structure |
|
* @return socket fd just to make sure that connection established |
|
* @see zclient_init |
|
* @see zclient_new |
|
*/ |
|
int |
|
zclient_socket_connect (struct zclient *zclient) |
|
{ |
|
#ifdef HAVE_TCP_ZEBRA |
|
zclient->sock = zclient_socket (); |
|
#else |
|
zclient->sock = zclient_socket_un (zclient_serv_path_get()); |
|
#endif |
|
return zclient->sock; |
|
} |
|
|
static int |
static int |
zclient_failed(struct zclient *zclient) |
zclient_failed(struct zclient *zclient) |
{ |
{ |
Line 233 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 259 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 287 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); |
} |
} |
|
|
|
static int |
|
zebra_hello_send (struct zclient *zclient) |
|
{ |
|
struct stream *s; |
|
|
|
if (zclient->redist_default) |
|
{ |
|
s = zclient->obuf; |
|
stream_reset (s); |
|
|
|
/* 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_putw_at (s, 0, stream_get_endp (s)); |
|
return zclient_send_message(zclient); |
|
} |
|
|
|
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 313 zclient_start (struct zclient *zclient)
|
Line 429 zclient_start (struct zclient *zclient)
|
if (zclient->t_connect) |
if (zclient->t_connect) |
return 0; |
return 0; |
|
|
/* Make socket. */ | if (zclient_socket_connect(zclient) < 0) |
#ifdef HAVE_TCP_ZEBRA | |
zclient->sock = zclient_socket (); | |
#else | |
zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH); | |
#endif /* HAVE_TCP_ZEBRA */ | |
if (zclient->sock < 0) | |
{ |
{ |
if (zclient_debug) |
if (zclient_debug) |
zlog_debug ("zclient connection fail"); |
zlog_debug ("zclient connection fail"); |
Line 339 zclient_start (struct zclient *zclient)
|
Line 449 zclient_start (struct zclient *zclient)
|
/* Create read thread. */ |
/* Create read thread. */ |
zclient_event (ZCLIENT_READ, zclient); |
zclient_event (ZCLIENT_READ, zclient); |
|
|
/* We need router-id information. */ | zebra_hello_send (zclient); |
zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD); | |
|
|
/* We need interface information. */ | /* Inform the successful connection. */ |
zebra_message_send (zclient, ZEBRA_INTERFACE_ADD); | if (zclient->zebra_connected) |
| (*zclient->zebra_connected) (zclient); |
|
|
/* 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 372 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 428 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); |
stream_putc (s, api->message); |
stream_putc (s, api->message); |
|
stream_putw (s, api->safi); |
|
|
/* Put prefix information. */ |
/* Put prefix information. */ |
psize = PSIZE (p->prefixlen); |
psize = PSIZE (p->prefixlen); |
Line 470 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 490 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); |
stream_putc (s, api->flags); |
stream_putc (s, api->flags); |
stream_putc (s, api->message); |
stream_putc (s, api->message); |
|
stream_putw (s, api->safi); |
|
|
/* Put prefix information. */ |
/* Put prefix information. */ |
psize = PSIZE (p->prefixlen); |
psize = PSIZE (p->prefixlen); |
Line 523 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 538 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 553 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 600 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 609 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); |
|
|
/* Read interface's index. */ | zebra_interface_if_set_value (s, ifp); |
ifp->ifindex = stream_getl (s); | |
|
|
/* Read interface's value. */ |
|
ifp->status = stream_getc (s); |
|
ifp->flags = stream_getq (s); |
|
ifp->metric = stream_getl (s); |
|
ifp->mtu = stream_getl (s); |
|
ifp->mtu6 = stream_getl (s); |
|
ifp->bandwidth = stream_getl (s); |
|
#ifdef HAVE_STRUCT_SOCKADDR_DL |
|
stream_get (&ifp->sdl, s, sizeof (ifp->sdl)); |
|
#else |
|
ifp->hw_addr_len = stream_getl (s); |
|
if (ifp->hw_addr_len) |
|
stream_get (ifp->hw_addr, s, ifp->hw_addr_len); |
|
#endif /* HAVE_STRUCT_SOCKADDR_DL */ |
|
|
|
return ifp; |
return ifp; |
} |
} |
|
|
Line 640 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 649 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) |
return NULL; |
return NULL; |
|
|
/* Read interface's index. */ | zebra_interface_if_set_value (s, ifp); |
ifp->ifindex = stream_getl (s); | |
|
|
/* Read interface's value. */ |
|
ifp->status = stream_getc (s); |
|
ifp->flags = stream_getq (s); |
|
ifp->metric = stream_getl (s); |
|
ifp->mtu = stream_getl (s); |
|
ifp->mtu6 = stream_getl (s); |
|
ifp->bandwidth = stream_getl (s); |
|
|
|
return ifp; |
return ifp; |
} |
} |
|
|
Line 715 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); |
|
ifp->ll_type = stream_getl (s); |
|
ifp->hw_addr_len = stream_getl (s); |
|
if (ifp->hw_addr_len) |
|
stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX)); |
} |
} |
|
|
static int |
static int |
Line 729 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 746 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 760 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 791 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) |
{ |
{ |
int ret; |
|
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 834 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 885 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) |
ret = (*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) |
ret = (*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) |
ret = (*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) |
ret = (*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) |
ret = (*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) |
ret = (*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) |
ret = (*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) |
ret = (*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) |
ret = (*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) |
ret = (*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) |
ret = (*zclient->ipv6_route_delete) (command, zclient, length); | (*zclient->ipv6_route_delete) (command, zclient, length, vrf_id); |
break; |
break; |
default: |
default: |
break; |
break; |
Line 949 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 999 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 1009 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 |
|
zclient_serv_path_set (char *path) |
|
{ |
|
struct stat sb; |
|
|
|
/* reset */ |
|
zclient_serv_path = NULL; |
|
|
|
/* test if `path' is socket. don't set it otherwise. */ |
|
if (stat(path, &sb) == -1) |
|
{ |
|
zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path); |
|
return; |
|
} |
|
|
|
if ((sb.st_mode & S_IFMT) != S_IFSOCK) |
|
{ |
|
zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path); |
|
return; |
|
} |
|
|
|
/* it seems that path is unix socket */ |
|
zclient_serv_path = path; |
|
} |
|
|