diff options
Diffstat (limited to 'lib/zclient.c')
-rw-r--r-- | lib/zclient.c | 151 |
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 |