summaryrefslogtreecommitdiffstats
path: root/lib/zclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c151
1 files changed, 92 insertions, 59 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index 71da87c6..8e443e28 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -93,15 +93,14 @@ zclient_init (struct zclient *zclient, int redist_default)
/* Clear redistribution flags. */
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
redistribution. */
zclient->redist_default = redist_default;
- zclient->redist[redist_default] = 1;
/* Set default-information redistribute to zero. */
- zclient->default_information = 0;
+ zclient->default_information = vrf_bitmap_init ();
/* Schedule first zclient connection. */
if (zclient_debug)
@@ -293,18 +292,19 @@ zclient_send_message(struct zclient *zclient)
}
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 */
stream_putw (s, ZEBRA_HEADER_SIZE);
stream_putc (s, ZEBRA_HEADER_MARKER);
stream_putc (s, ZSERV_VERSION);
+ stream_putw (s, vrf_id);
stream_putw (s, command);
}
/* Send simple Zebra message. */
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;
@@ -313,7 +313,7 @@ zebra_message_send (struct zclient *zclient, int command)
stream_reset (s);
/* Send very simple command only Zebra message. */
- zclient_create_header (s, command);
+ zclient_create_header (s, command, vrf_id);
return zclient_send_message(zclient);
}
@@ -328,7 +328,8 @@ zebra_hello_send (struct zclient *zclient)
s = zclient->obuf;
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_putw_at (s, 0, stream_get_endp (s));
return zclient_send_message(zclient);
@@ -337,12 +338,47 @@ zebra_hello_send (struct zclient *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. */
int
zclient_start (struct zclient *zclient)
{
- int i;
-
if (zclient_debug)
zlog_debug ("zclient_start is called");
@@ -380,20 +416,9 @@ zclient_start (struct zclient *zclient)
zebra_hello_send (zclient);
- /* We need router-id information. */
- zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD);
-
- /* 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);
+ /* Inform the successful connection. */
+ if (zclient->zebra_connected)
+ (*zclient->zebra_connected) (zclient);
return 0;
}
@@ -469,8 +494,8 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
/* Reset stream. */
s = zclient->obuf;
stream_reset (s);
-
- zclient_create_header (s, cmd);
+
+ zclient_create_header (s, cmd, api->vrf_id);
/* Put type and nexthop. */
stream_putc (s, api->type);
@@ -532,7 +557,7 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
s = zclient->obuf;
stream_reset (s);
- zclient_create_header (s, cmd);
+ zclient_create_header (s, cmd, api->vrf_id);
/* Put type and nexthop. */
stream_putc (s, api->type);
@@ -581,14 +606,15 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
* sending client
*/
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;
s = zclient->obuf;
stream_reset(s);
- zclient_create_header (s, command);
+ zclient_create_header (s, command, vrf_id);
stream_putc (s, type);
stream_putw_at (s, 0, stream_get_endp (s));
@@ -643,7 +669,7 @@ zebra_router_id_update_read (struct stream *s, struct prefix *rid)
*/
struct interface *
-zebra_interface_add_read (struct stream *s)
+zebra_interface_add_read (struct stream *s, vrf_id_t vrf_id)
{
struct interface *ifp;
char ifname_tmp[INTERFACE_NAMSIZ];
@@ -652,7 +678,9 @@ zebra_interface_add_read (struct stream *s)
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
/* 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);
@@ -667,7 +695,7 @@ zebra_interface_add_read (struct stream *s)
* is sent at the tail of the message.
*/
struct interface *
-zebra_interface_state_read (struct stream *s)
+zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
{
struct interface *ifp;
char ifname_tmp[INTERFACE_NAMSIZ];
@@ -676,8 +704,9 @@ zebra_interface_state_read (struct stream *s)
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
/* Lookup this by interface index. */
- ifp = if_lookup_by_name_len (ifname_tmp,
- strnlen(ifname_tmp, INTERFACE_NAMSIZ));
+ ifp = if_lookup_by_name_len_vrf (ifname_tmp,
+ strnlen (ifname_tmp, INTERFACE_NAMSIZ),
+ vrf_id);
/* If such interface does not exist, indicate an error */
if (! ifp)
@@ -754,7 +783,7 @@ memconstant(const void *s, int c, size_t n)
}
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;
struct interface *ifp;
@@ -771,7 +800,7 @@ zebra_interface_address_read (int type, struct stream *s)
ifindex = stream_getl (s);
/* Lookup index. */
- ifp = if_lookup_by_index (ifindex);
+ ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
if (ifp == NULL)
{
zlog_warn ("zebra_interface_address_read(%s): "
@@ -834,6 +863,7 @@ zclient_read (struct thread *thread)
size_t already;
uint16_t length, command;
uint8_t marker, version;
+ vrf_id_t vrf_id;
struct zclient *zclient;
/* Get socket to zebra. */
@@ -868,6 +898,7 @@ zclient_read (struct thread *thread)
length = stream_getw (zclient->ibuf);
marker = stream_getc (zclient->ibuf);
version = stream_getc (zclient->ibuf);
+ vrf_id = stream_getw (zclient->ibuf);
command = stream_getw (zclient->ibuf);
if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
@@ -919,53 +950,53 @@ zclient_read (struct thread *thread)
length -= ZEBRA_HEADER_SIZE;
if (zclient_debug)
- zlog_debug("zclient 0x%p command 0x%x \n", (void *)zclient, command);
+ zlog_debug("zclient 0x%p command 0x%x VRF %u\n", (void *)zclient, command, vrf_id);
switch (command)
{
case ZEBRA_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;
case ZEBRA_INTERFACE_ADD:
if (zclient->interface_add)
- (*zclient->interface_add) (command, zclient, length);
+ (*zclient->interface_add) (command, zclient, length, vrf_id);
break;
case ZEBRA_INTERFACE_DELETE:
if (zclient->interface_delete)
- (*zclient->interface_delete) (command, zclient, length);
+ (*zclient->interface_delete) (command, zclient, length, vrf_id);
break;
case ZEBRA_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;
case ZEBRA_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;
case ZEBRA_INTERFACE_UP:
if (zclient->interface_up)
- (*zclient->interface_up) (command, zclient, length);
+ (*zclient->interface_up) (command, zclient, length, vrf_id);
break;
case ZEBRA_INTERFACE_DOWN:
if (zclient->interface_down)
- (*zclient->interface_down) (command, zclient, length);
+ (*zclient->interface_down) (command, zclient, length, vrf_id);
break;
case ZEBRA_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;
case ZEBRA_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;
case ZEBRA_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;
case ZEBRA_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;
default:
break;
@@ -983,46 +1014,48 @@ zclient_read (struct thread *thread)
}
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 (zclient->redist[type])
+ if (vrf_bitmap_check (zclient->redist[type], vrf_id))
return;
- zclient->redist[type] = 1;
+ vrf_bitmap_set (zclient->redist[type], vrf_id);
}
else
{
- if (!zclient->redist[type])
+ if (!vrf_bitmap_check (zclient->redist[type], vrf_id))
return;
- zclient->redist[type] = 0;
+ vrf_bitmap_unset (zclient->redist[type], vrf_id);
}
if (zclient->sock > 0)
- zebra_redistribute_send (command, zclient, type);
+ zebra_redistribute_send (command, zclient, type, vrf_id);
}
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 (zclient->default_information)
+ if (vrf_bitmap_check (zclient->default_information, vrf_id))
return;
- zclient->default_information = 1;
+ vrf_bitmap_set (zclient->default_information, vrf_id);
}
else
{
- if (!zclient->default_information)
+ if (!vrf_bitmap_check (zclient->default_information, vrf_id))
return;
- zclient->default_information = 0;
+ vrf_bitmap_unset (zclient->default_information, vrf_id);
}
if (zclient->sock > 0)
- zebra_message_send (zclient, command);
+ zebra_message_send (zclient, command, vrf_id);
}
static void