|
@@ -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
|