diff options
Diffstat (limited to 'zebra/zserv.c')
-rw-r--r-- | zebra/zserv.c | 4917 |
1 files changed, 2425 insertions, 2492 deletions
diff --git a/zebra/zserv.c b/zebra/zserv.c index 15feb78c0..3bc5f83f6 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -59,150 +59,145 @@ /* Event list of zebra. */ enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE }; -static void zebra_event (enum event event, int sock, struct zserv *client); +static void zebra_event(enum event event, int sock, struct zserv *client); extern struct zebra_privs_t zserv_privs; -static void zebra_client_close (struct zserv *client); - -static int -zserv_delayed_close(struct thread *thread) -{ - struct zserv *client = THREAD_ARG(thread); - - client->t_suicide = NULL; - zebra_client_close(client); - return 0; -} - -static int -zserv_flush_data(struct thread *thread) -{ - struct zserv *client = THREAD_ARG(thread); - - client->t_write = NULL; - if (client->t_suicide) - { - zebra_client_close(client); - return -1; - } - switch (buffer_flush_available(client->wb, client->sock)) - { - case BUFFER_ERROR: - zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, " - "closing", __func__, client->sock); - zebra_client_close(client); - client = NULL; - break; - case BUFFER_PENDING: - client->t_write = NULL; - thread_add_write(zebrad.master, zserv_flush_data, client, client->sock, - &client->t_write); - break; - case BUFFER_EMPTY: - break; - } - - if (client) - client->last_write_time = monotime(NULL); - return 0; -} - -int -zebra_server_send_message(struct zserv *client) -{ - if (client->t_suicide) - return -1; - - if (client->is_synchronous) - return 0; - - stream_set_getp(client->obuf, 0); - client->last_write_cmd = stream_getw_from(client->obuf, 6); - switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf), - stream_get_endp(client->obuf))) - { - case BUFFER_ERROR: - zlog_warn("%s: buffer_write failed to zserv client fd %d, closing", - __func__, client->sock); - /* Schedule a delayed close since many of the functions that call this - one do not check the return code. They do not allow for the - possibility that an I/O error may have caused the client to be - deleted. */ - client->t_suicide = NULL; - thread_add_event(zebrad.master, zserv_delayed_close, client, 0, - &client->t_suicide); - return -1; - case BUFFER_EMPTY: - THREAD_OFF(client->t_write); - break; - case BUFFER_PENDING: - thread_add_write(zebrad.master, zserv_flush_data, client, client->sock, - &client->t_write); - break; - } - - client->last_write_time = monotime(NULL); - return 0; -} - -void -zserv_create_header (struct stream *s, uint16_t cmd, 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, cmd); -} - -static void -zserv_encode_interface (struct stream *s, struct interface *ifp) -{ - /* Interface information. */ - stream_put (s, ifp->name, INTERFACE_NAMSIZ); - stream_putl (s, ifp->ifindex); - stream_putc (s, ifp->status); - stream_putq (s, ifp->flags); - stream_putc (s, ifp->ptm_enable); - stream_putc (s, ifp->ptm_status); - stream_putl (s, ifp->metric); - stream_putl (s, ifp->speed); - stream_putl (s, ifp->mtu); - stream_putl (s, ifp->mtu6); - stream_putl (s, ifp->bandwidth); - stream_putl (s, ifp->ll_type); - stream_putl (s, ifp->hw_addr_len); - if (ifp->hw_addr_len) - stream_put (s, ifp->hw_addr, ifp->hw_addr_len); - - /* Then, Traffic Engineering parameters if any */ - if (HAS_LINK_PARAMS(ifp) && IS_LINK_PARAMS_SET(ifp->link_params)) - { - stream_putc (s, 1); - zebra_interface_link_params_write (s, ifp); - } - else - stream_putc (s, 0); - - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); -} - -static void -zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf) -{ - struct vrf_data data; - - data.l.table_id = zvrf->table_id; - /* Pass the tableid */ - stream_put (s, &data, sizeof (struct vrf_data)); - /* Interface information. */ - stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ); - - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); +static void zebra_client_close(struct zserv *client); + +static int zserv_delayed_close(struct thread *thread) +{ + struct zserv *client = THREAD_ARG(thread); + + client->t_suicide = NULL; + zebra_client_close(client); + return 0; +} + +static int zserv_flush_data(struct thread *thread) +{ + struct zserv *client = THREAD_ARG(thread); + + client->t_write = NULL; + if (client->t_suicide) { + zebra_client_close(client); + return -1; + } + switch (buffer_flush_available(client->wb, client->sock)) { + case BUFFER_ERROR: + zlog_warn( + "%s: buffer_flush_available failed on zserv client fd %d, " + "closing", + __func__, client->sock); + zebra_client_close(client); + client = NULL; + break; + case BUFFER_PENDING: + client->t_write = NULL; + thread_add_write(zebrad.master, zserv_flush_data, client, + client->sock, &client->t_write); + break; + case BUFFER_EMPTY: + break; + } + + if (client) + client->last_write_time = monotime(NULL); + return 0; +} + +int zebra_server_send_message(struct zserv *client) +{ + if (client->t_suicide) + return -1; + + if (client->is_synchronous) + return 0; + + stream_set_getp(client->obuf, 0); + client->last_write_cmd = stream_getw_from(client->obuf, 6); + switch (buffer_write(client->wb, client->sock, + STREAM_DATA(client->obuf), + stream_get_endp(client->obuf))) { + case BUFFER_ERROR: + zlog_warn( + "%s: buffer_write failed to zserv client fd %d, closing", + __func__, client->sock); + /* Schedule a delayed close since many of the functions that + call this + one do not check the return code. They do not allow for the + possibility that an I/O error may have caused the client to + be + deleted. */ + client->t_suicide = NULL; + thread_add_event(zebrad.master, zserv_delayed_close, client, 0, + &client->t_suicide); + return -1; + case BUFFER_EMPTY: + THREAD_OFF(client->t_write); + break; + case BUFFER_PENDING: + thread_add_write(zebrad.master, zserv_flush_data, client, + client->sock, &client->t_write); + break; + } + + client->last_write_time = monotime(NULL); + return 0; +} + +void zserv_create_header(struct stream *s, uint16_t cmd, 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, cmd); +} + +static void zserv_encode_interface(struct stream *s, struct interface *ifp) +{ + /* Interface information. */ + stream_put(s, ifp->name, INTERFACE_NAMSIZ); + stream_putl(s, ifp->ifindex); + stream_putc(s, ifp->status); + stream_putq(s, ifp->flags); + stream_putc(s, ifp->ptm_enable); + stream_putc(s, ifp->ptm_status); + stream_putl(s, ifp->metric); + stream_putl(s, ifp->speed); + stream_putl(s, ifp->mtu); + stream_putl(s, ifp->mtu6); + stream_putl(s, ifp->bandwidth); + stream_putl(s, ifp->ll_type); + stream_putl(s, ifp->hw_addr_len); + if (ifp->hw_addr_len) + stream_put(s, ifp->hw_addr, ifp->hw_addr_len); + + /* Then, Traffic Engineering parameters if any */ + if (HAS_LINK_PARAMS(ifp) && IS_LINK_PARAMS_SET(ifp->link_params)) { + stream_putc(s, 1); + zebra_interface_link_params_write(s, ifp); + } else + stream_putc(s, 0); + + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); +} + +static void zserv_encode_vrf(struct stream *s, struct zebra_vrf *zvrf) +{ + struct vrf_data data; + + data.l.table_id = zvrf->table_id; + /* Pass the tableid */ + stream_put(s, &data, sizeof(struct vrf_data)); + /* Interface information. */ + stream_put(s, zvrf_name(zvrf), VRF_NAMSIZ); + + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); } /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */ @@ -216,99 +211,94 @@ zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf) * an interface is marked IFF_UP (i.e., an RTM_IFINFO message is * received) */ -int -zsend_interface_add (struct zserv *client, struct interface *ifp) +int zsend_interface_add(struct zserv *client, struct interface *ifp) { - struct stream *s; + struct stream *s; - s = client->obuf; - stream_reset (s); + s = client->obuf; + stream_reset(s); - zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id); - zserv_encode_interface (s, ifp); + zserv_create_header(s, ZEBRA_INTERFACE_ADD, ifp->vrf_id); + zserv_encode_interface(s, ifp); - client->ifadd_cnt++; - return zebra_server_send_message(client); + client->ifadd_cnt++; + return zebra_server_send_message(client); } /* Interface deletion from zebra daemon. */ -int -zsend_interface_delete (struct zserv *client, struct interface *ifp) +int zsend_interface_delete(struct zserv *client, struct interface *ifp) { - struct stream *s; + struct stream *s; - s = client->obuf; - stream_reset (s); + s = client->obuf; + stream_reset(s); - zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id); - zserv_encode_interface (s, ifp); + zserv_create_header(s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id); + zserv_encode_interface(s, ifp); - client->ifdel_cnt++; - return zebra_server_send_message (client); + client->ifdel_cnt++; + return zebra_server_send_message(client); } -int -zsend_vrf_add (struct zserv *client, struct zebra_vrf *zvrf) +int zsend_vrf_add(struct zserv *client, struct zebra_vrf *zvrf) { - struct stream *s; + struct stream *s; - s = client->obuf; - stream_reset (s); + s = client->obuf; + stream_reset(s); - zserv_create_header (s, ZEBRA_VRF_ADD, zvrf_id (zvrf)); - zserv_encode_vrf (s, zvrf); + zserv_create_header(s, ZEBRA_VRF_ADD, zvrf_id(zvrf)); + zserv_encode_vrf(s, zvrf); - client->vrfadd_cnt++; - return zebra_server_send_message(client); + client->vrfadd_cnt++; + return zebra_server_send_message(client); } /* VRF deletion from zebra daemon. */ -int -zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf) +int zsend_vrf_delete(struct zserv *client, struct zebra_vrf *zvrf) { - struct stream *s; + struct stream *s; - s = client->obuf; - stream_reset (s); + s = client->obuf; + stream_reset(s); - zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf_id (zvrf)); - zserv_encode_vrf (s, zvrf); + zserv_create_header(s, ZEBRA_VRF_DELETE, zvrf_id(zvrf)); + zserv_encode_vrf(s, zvrf); - client->vrfdel_cnt++; - return zebra_server_send_message (client); + client->vrfdel_cnt++; + return zebra_server_send_message(client); } -int -zsend_interface_link_params (struct zserv *client, struct interface *ifp) +int zsend_interface_link_params(struct zserv *client, struct interface *ifp) { - struct stream *s; + struct stream *s; - /* Check this client need interface information. */ - if (! client->ifinfo) - return 0; + /* Check this client need interface information. */ + if (!client->ifinfo) + return 0; - if (!ifp->link_params) - return 0; - s = client->obuf; - stream_reset (s); + if (!ifp->link_params) + return 0; + s = client->obuf; + stream_reset(s); - zserv_create_header (s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id); + zserv_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id); - /* Add Interface Index */ - stream_putl (s, ifp->ifindex); + /* Add Interface Index */ + stream_putl(s, ifp->ifindex); - /* Then TE Link Parameters */ - if (zebra_interface_link_params_write (s, ifp) == 0) - return 0; + /* Then TE Link Parameters */ + if (zebra_interface_link_params_write(s, ifp) == 0) + return 0; - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); - return zebra_server_send_message (client); + return zebra_server_send_message(client); } /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or - * ZEBRA_INTERFACE_ADDRESS_DELETE to the client. + * ZEBRA_INTERFACE_ADDRESS_DELETE to the client. * * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations: * - in response to a 3-byte ZEBRA_INTERFACE_ADD request @@ -323,13 +313,13 @@ zsend_interface_link_params (struct zserv *client, struct interface *ifp) * - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]" * and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M" * - when an RTM_NEWADDR message is received from the kernel, - * - * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE: + * + * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE: * * zsend_interface_address(DELETE) - * ^ - * | - * zebra_interface_address_delete_update + * ^ + * | + * zebra_interface_address_delete_update * ^ ^ ^ * | | if_delete_update * | | @@ -345,232 +335,230 @@ zsend_interface_link_params (struct zserv *client, struct interface *ifp) * ["no ipv6 address X:X::X:X/M"] * */ -int -zsend_interface_address (int cmd, struct zserv *client, - struct interface *ifp, struct connected *ifc) -{ - int blen; - struct stream *s; - struct prefix *p; - - s = client->obuf; - stream_reset (s); - - zserv_create_header (s, cmd, ifp->vrf_id); - stream_putl (s, ifp->ifindex); - - /* Interface address flag. */ - stream_putc (s, ifc->flags); - - /* Prefix information. */ - p = ifc->address; - stream_putc (s, p->family); - blen = prefix_blen (p); - stream_put (s, &p->u.prefix, blen); - - /* - * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE - * but zebra_interface_address_delete_read() in the gnu version - * expects to find it - */ - stream_putc (s, p->prefixlen); - - /* Destination. */ - p = ifc->destination; - if (p) - stream_put (s, &p->u.prefix, blen); - else - stream_put (s, NULL, blen); +int zsend_interface_address(int cmd, struct zserv *client, + struct interface *ifp, struct connected *ifc) +{ + int blen; + struct stream *s; + struct prefix *p; + + s = client->obuf; + stream_reset(s); + + zserv_create_header(s, cmd, ifp->vrf_id); + stream_putl(s, ifp->ifindex); + + /* Interface address flag. */ + stream_putc(s, ifc->flags); + + /* Prefix information. */ + p = ifc->address; + stream_putc(s, p->family); + blen = prefix_blen(p); + stream_put(s, &p->u.prefix, blen); + + /* + * XXX gnu version does not send prefixlen for + * ZEBRA_INTERFACE_ADDRESS_DELETE + * but zebra_interface_address_delete_read() in the gnu version + * expects to find it + */ + stream_putc(s, p->prefixlen); + + /* Destination. */ + p = ifc->destination; + if (p) + stream_put(s, &p->u.prefix, blen); + else + stream_put(s, NULL, blen); - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); - client->connected_rt_add_cnt++; - return zebra_server_send_message(client); + client->connected_rt_add_cnt++; + return zebra_server_send_message(client); } -static int -zsend_interface_nbr_address (int cmd, struct zserv *client, - struct interface *ifp, struct nbr_connected *ifc) +static int zsend_interface_nbr_address(int cmd, struct zserv *client, + struct interface *ifp, + struct nbr_connected *ifc) { - int blen; - struct stream *s; - struct prefix *p; + int blen; + struct stream *s; + struct prefix *p; - s = client->obuf; - stream_reset (s); + s = client->obuf; + stream_reset(s); - zserv_create_header (s, cmd, ifp->vrf_id); - stream_putl (s, ifp->ifindex); + zserv_create_header(s, cmd, ifp->vrf_id); + stream_putl(s, ifp->ifindex); - /* Prefix information. */ - p = ifc->address; - stream_putc (s, p->family); - blen = prefix_blen (p); - stream_put (s, &p->u.prefix, blen); + /* Prefix information. */ + p = ifc->address; + stream_putc(s, p->family); + blen = prefix_blen(p); + stream_put(s, &p->u.prefix, blen); - /* - * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE - * but zebra_interface_address_delete_read() in the gnu version - * expects to find it - */ - stream_putc (s, p->prefixlen); + /* + * XXX gnu version does not send prefixlen for + * ZEBRA_INTERFACE_ADDRESS_DELETE + * but zebra_interface_address_delete_read() in the gnu version + * expects to find it + */ + stream_putc(s, p->prefixlen); - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); - return zebra_server_send_message(client); + return zebra_server_send_message(client); } /* Interface address addition. */ -static void -zebra_interface_nbr_address_add_update (struct interface *ifp, - struct nbr_connected *ifc) -{ - struct listnode *node, *nnode; - struct zserv *client; - struct prefix *p; - - if (IS_ZEBRA_DEBUG_EVENT) - { - char buf[INET6_ADDRSTRLEN]; - - p = ifc->address; - zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s", - inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN), - p->prefixlen, ifc->ifp->name); - } +static void zebra_interface_nbr_address_add_update(struct interface *ifp, + struct nbr_connected *ifc) +{ + struct listnode *node, *nnode; + struct zserv *client; + struct prefix *p; + + if (IS_ZEBRA_DEBUG_EVENT) { + char buf[INET6_ADDRSTRLEN]; + + p = ifc->address; + zlog_debug( + "MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s", + inet_ntop(p->family, &p->u.prefix, buf, + INET6_ADDRSTRLEN), + p->prefixlen, ifc->ifp->name); + } - for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) - zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, ifp, ifc); + for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) + zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD, + client, ifp, ifc); } /* Interface address deletion. */ -static void -zebra_interface_nbr_address_delete_update (struct interface *ifp, - struct nbr_connected *ifc) -{ - struct listnode *node, *nnode; - struct zserv *client; - struct prefix *p; - - if (IS_ZEBRA_DEBUG_EVENT) - { - char buf[INET6_ADDRSTRLEN]; - - p = ifc->address; - zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s", - inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN), - p->prefixlen, ifc->ifp->name); - } +static void zebra_interface_nbr_address_delete_update(struct interface *ifp, + struct nbr_connected *ifc) +{ + struct listnode *node, *nnode; + struct zserv *client; + struct prefix *p; + + if (IS_ZEBRA_DEBUG_EVENT) { + char buf[INET6_ADDRSTRLEN]; + + p = ifc->address; + zlog_debug( + "MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s", + inet_ntop(p->family, &p->u.prefix, buf, + INET6_ADDRSTRLEN), + p->prefixlen, ifc->ifp->name); + } - for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) - zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc); + for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) + zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, + client, ifp, ifc); } /* Send addresses on interface to client */ -int -zsend_interface_addresses (struct zserv *client, struct interface *ifp) +int zsend_interface_addresses(struct zserv *client, struct interface *ifp) { - struct listnode *cnode, *cnnode; - struct connected *c; - struct nbr_connected *nc; + struct listnode *cnode, *cnnode; + struct connected *c; + struct nbr_connected *nc; - /* Send interface addresses. */ - for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c)) - { - if (!CHECK_FLAG (c->conf, ZEBRA_IFC_REAL)) - continue; + /* Send interface addresses. */ + for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) { + if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL)) + continue; - if (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, - ifp, c) < 0) - return -1; - } + if (zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD, client, + ifp, c) + < 0) + return -1; + } - /* Send interface neighbors. */ - for (ALL_LIST_ELEMENTS (ifp->nbr_connected, cnode, cnnode, nc)) - { - if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, - client, ifp, nc) < 0) - return -1; - } + /* Send interface neighbors. */ + for (ALL_LIST_ELEMENTS(ifp->nbr_connected, cnode, cnnode, nc)) { + if (zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD, + client, ifp, nc) + < 0) + return -1; + } - return 0; + return 0; } /* Notify client about interface moving from one VRF to another. * Whether client is interested in old and new VRF is checked by caller. */ -int -zsend_interface_vrf_update (struct zserv *client, struct interface *ifp, - vrf_id_t vrf_id) +int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp, + vrf_id_t vrf_id) { - struct stream *s; + struct stream *s; - s = client->obuf; - stream_reset (s); + s = client->obuf; + stream_reset(s); - zserv_create_header (s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id); + zserv_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id); - /* Fill in the ifIndex of the interface and its new VRF (id) */ - stream_putl (s, ifp->ifindex); - stream_putw (s, vrf_id); + /* Fill in the ifIndex of the interface and its new VRF (id) */ + stream_putl(s, ifp->ifindex); + stream_putw(s, vrf_id); - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); - client->if_vrfchg_cnt++; - return zebra_server_send_message(client); + client->if_vrfchg_cnt++; + return zebra_server_send_message(client); } /* Add new nbr connected IPv6 address */ -void -nbr_connected_add_ipv6 (struct interface *ifp, struct in6_addr *address) +void nbr_connected_add_ipv6(struct interface *ifp, struct in6_addr *address) { - struct nbr_connected *ifc; - struct prefix p; + struct nbr_connected *ifc; + struct prefix p; - p.family = AF_INET6; - IPV6_ADDR_COPY (&p.u.prefix, address); - p.prefixlen = IPV6_MAX_PREFIXLEN; + p.family = AF_INET6; + IPV6_ADDR_COPY(&p.u.prefix, address); + p.prefixlen = IPV6_MAX_PREFIXLEN; - if (!(ifc = listnode_head(ifp->nbr_connected))) - { - /* new addition */ - ifc = nbr_connected_new (); - ifc->address = prefix_new(); - ifc->ifp = ifp; - listnode_add (ifp->nbr_connected, ifc); - } + if (!(ifc = listnode_head(ifp->nbr_connected))) { + /* new addition */ + ifc = nbr_connected_new(); + ifc->address = prefix_new(); + ifc->ifp = ifp; + listnode_add(ifp->nbr_connected, ifc); + } - prefix_copy(ifc->address, &p); + prefix_copy(ifc->address, &p); - zebra_interface_nbr_address_add_update (ifp, ifc); + zebra_interface_nbr_address_add_update(ifp, ifc); - if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 1); + if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, address, 1); } -void -nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address) +void nbr_connected_delete_ipv6(struct interface *ifp, struct in6_addr *address) { - struct nbr_connected *ifc; - struct prefix p; + struct nbr_connected *ifc; + struct prefix p; - p.family = AF_INET6; - IPV6_ADDR_COPY (&p.u.prefix, address); - p.prefixlen = IPV6_MAX_PREFIXLEN; + p.family = AF_INET6; + IPV6_ADDR_COPY(&p.u.prefix, address); + p.prefixlen = IPV6_MAX_PREFIXLEN; - ifc = nbr_connected_check(ifp, &p); - if (!ifc) - return; + ifc = nbr_connected_check(ifp, &p); + if (!ifc) + return; - listnode_delete (ifp->nbr_connected, ifc); + listnode_delete(ifp->nbr_connected, ifc); - zebra_interface_nbr_address_delete_update (ifp, ifc); + zebra_interface_nbr_address_delete_update(ifp, ifc); - if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 0); + if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, address, 0); - nbr_connected_free (ifc); + nbr_connected_free(ifc); } /* @@ -583,23 +571,22 @@ nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address) * - a vty command modifying the bandwidth of an interface is received. * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected. */ -int -zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp) +int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp) { - struct stream *s; + struct stream *s; - s = client->obuf; - stream_reset (s); + s = client->obuf; + stream_reset(s); - zserv_create_header (s, cmd, ifp->vrf_id); - zserv_encode_interface (s, ifp); + zserv_create_header(s, cmd, ifp->vrf_id); + zserv_encode_interface(s, ifp); - if (cmd == ZEBRA_INTERFACE_UP) - client->ifup_cnt++; - else - client->ifdown_cnt++; + if (cmd == ZEBRA_INTERFACE_UP) + client->ifup_cnt++; + else + client->ifdown_cnt++; - return zebra_server_send_message(client); + return zebra_server_send_message(client); } /* @@ -609,441 +596,413 @@ zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp) * away or ignored by the receiver. This is the leaner function that is not a * duplicate of the zapi_ipv4_route_add/del. * - * The primary difference is that this function merely sends a single NH instead of + * The primary difference is that this function merely sends a single NH instead + * of * all the nexthops. */ -int -zsend_redistribute_route (int add, struct zserv *client, struct prefix *p, - struct prefix *src_p, struct route_entry *re) -{ - afi_t afi; - int cmd; - int psize; - struct stream *s; - struct nexthop *nexthop; - unsigned long nhnummark = 0, messmark = 0; - int nhnum = 0; - u_char zapi_flags = 0; - struct nexthop dummy_nh; - - afi = family2afi (p->family); - if (add) - { - switch (afi) - { - case AFI_IP: - cmd = ZEBRA_REDISTRIBUTE_IPV4_ADD; - client->redist_v4_add_cnt++; - break; - case AFI_IP6: - cmd = ZEBRA_REDISTRIBUTE_IPV6_ADD; - client->redist_v6_add_cnt++; - break; - default: - return -1; - } - } - else - { - switch (afi) - { - case AFI_IP: - cmd = ZEBRA_REDISTRIBUTE_IPV4_DEL; - client->redist_v4_del_cnt++; - break; - case AFI_IP6: - cmd = ZEBRA_REDISTRIBUTE_IPV6_DEL; - client->redist_v6_del_cnt++; - break; - default: - return -1; - } - } - - s = client->obuf; - stream_reset (s); - memset(&dummy_nh, 0, sizeof(struct nexthop)); - - zserv_create_header (s, cmd, re->vrf_id); - - /* Put type and nexthop. */ - stream_putc (s, re->type); - stream_putw (s, re->instance); - stream_putl (s, re->flags); - - /* marker for message flags field */ - messmark = stream_get_endp (s); - stream_putc (s, 0); - - /* Prefix. */ - psize = PSIZE (p->prefixlen); - stream_putc (s, p->prefixlen); - stream_write (s, (u_char *) & p->u.prefix, psize); - - if (src_p) - { - SET_FLAG (zapi_flags, ZAPI_MESSAGE_SRCPFX); - psize = PSIZE (src_p->prefixlen); - stream_putc (s, src_p->prefixlen); - stream_write (s, (u_char *) & src_p->u.prefix, psize); - } - - for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) - { - /* We don't send any nexthops when there's a multipath */ - if (re->nexthop_active_num > 1 && client->proto != ZEBRA_ROUTE_LDP) - { - SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); - - stream_putc(s, 1); - if (p->family == AF_INET) - { - stream_put_in_addr (s, &dummy_nh.gate.ipv4); - } - else if (p->family == AF_INET6) - { - stream_write (s, (u_char *) &dummy_nh.gate.ipv6, 16); - } - else - { - /* We don't handle anything else now, abort */ - zlog_err("%s: Unable to redistribute route of unknown family, %d\n", - __func__, p->family); - return -1; - } - stream_putc (s, 1); - stream_putl (s, 0); /* dummy ifindex */ - break; +int zsend_redistribute_route(int add, struct zserv *client, struct prefix *p, + struct prefix *src_p, struct route_entry *re) +{ + afi_t afi; + int cmd; + int psize; + struct stream *s; + struct nexthop *nexthop; + unsigned long nhnummark = 0, messmark = 0; + int nhnum = 0; + u_char zapi_flags = 0; + struct nexthop dummy_nh; + + afi = family2afi(p->family); + if (add) { + switch (afi) { + case AFI_IP: + cmd = ZEBRA_REDISTRIBUTE_IPV4_ADD; + client->redist_v4_add_cnt++; + break; + case AFI_IP6: + cmd = ZEBRA_REDISTRIBUTE_IPV6_ADD; + client->redist_v6_add_cnt++; + break; + default: + return -1; + } + } else { + switch (afi) { + case AFI_IP: + cmd = ZEBRA_REDISTRIBUTE_IPV4_DEL; + client->redist_v4_del_cnt++; + break; + case AFI_IP6: + cmd = ZEBRA_REDISTRIBUTE_IPV6_DEL; + client->redist_v6_del_cnt++; + break; + default: + return -1; + } } - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - { - SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); - SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); - if (nhnummark == 0) - { - nhnummark = stream_get_endp (s); - stream_putc (s, 1); /* placeholder */ - } - nhnum++; - - switch(nexthop->type) - { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - stream_put_in_addr (s, &nexthop->gate.ipv4); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - /* Only BGP supports IPv4 prefix with IPv6 NH, so kill this */ - if (p->family == AF_INET) - stream_put_in_addr(s, &dummy_nh.gate.ipv4); - else - stream_write (s, (u_char *) &nexthop->gate.ipv6, 16); - break; - default: - if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD - || cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL) - { - struct in_addr empty; - memset (&empty, 0, sizeof (struct in_addr)); - stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN); - } - else - { - struct in6_addr empty; - memset (&empty, 0, sizeof (struct in6_addr)); - stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN); - } - } - - /* Interface index. */ - stream_putc (s, 1); - stream_putl (s, nexthop->ifindex); - - /* ldpd needs all nexthops */ - if (client->proto != ZEBRA_ROUTE_LDP) - break; - } - } - - /* Distance */ - SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE); - stream_putc (s, re->distance); - - /* Metric */ - SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC); - stream_putl (s, re->metric); - - /* Tag */ - if (re->tag) - { - SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG); - stream_putl(s, re->tag); - } - - /* MTU */ - SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU); - stream_putl (s, re->mtu); - - /* write real message flags value */ - stream_putc_at (s, messmark, zapi_flags); - - /* Write next-hop number */ - if (nhnummark) - stream_putc_at (s, nhnummark, nhnum); - - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); - - return zebra_server_send_message(client); -} - -static int -zsend_write_nexthop (struct stream *s, struct nexthop *nexthop) -{ - stream_putc (s, nexthop->type); - switch (nexthop->type) - { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - stream_put_in_addr (s, &nexthop->gate.ipv4); - stream_putl (s, nexthop->ifindex); - break; - case NEXTHOP_TYPE_IPV6: - stream_put (s, &nexthop->gate.ipv6, 16); - break; - case NEXTHOP_TYPE_IPV6_IFINDEX: - stream_put (s, &nexthop->gate.ipv6, 16); - stream_putl (s, nexthop->ifindex); - break; - case NEXTHOP_TYPE_IFINDEX: - stream_putl (s, nexthop->ifindex); - break; - default: - /* do nothing */ - break; - } - return 1; -} + s = client->obuf; + stream_reset(s); + memset(&dummy_nh, 0, sizeof(struct nexthop)); -/* Nexthop register */ -static int -zserv_rnh_register (struct zserv *client, int sock, u_short length, - rnh_type_t type, struct zebra_vrf *zvrf) -{ - struct rnh *rnh; - struct stream *s; - struct prefix p; - u_short l = 0; - u_char flags = 0; - - if (IS_ZEBRA_DEBUG_NHT) - zlog_debug("rnh_register msg from client %s: length=%d, type=%s\n", - zebra_route_string(client->proto), length, - (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route"); - - s = client->ibuf; - - client->nh_reg_time = monotime(NULL); - - while (l < length) - { - flags = stream_getc(s); - p.family = stream_getw(s); - p.prefixlen = stream_getc(s); - l += 4; - if (p.family == AF_INET) - { - p.u.prefix4.s_addr = stream_get_ipv4(s); - l += IPV4_MAX_BYTELEN; - } - else if (p.family == AF_INET6) - { - stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); - l += IPV6_MAX_BYTELEN; - } - else - { - zlog_err("rnh_register: Received unknown family type %d\n", - p.family); - return -1; + zserv_create_header(s, cmd, re->vrf_id); + + /* Put type and nexthop. */ + stream_putc(s, re->type); + stream_putw(s, re->instance); + stream_putl(s, re->flags); + + /* marker for message flags field */ + messmark = stream_get_endp(s); + stream_putc(s, 0); + + /* Prefix. */ + psize = PSIZE(p->prefixlen); + stream_putc(s, p->prefixlen); + stream_write(s, (u_char *)&p->u.prefix, psize); + + if (src_p) { + SET_FLAG(zapi_flags, ZAPI_MESSAGE_SRCPFX); + psize = PSIZE(src_p->prefixlen); + stream_putc(s, src_p->prefixlen); + stream_write(s, (u_char *)&src_p->u.prefix, psize); } - rnh = zebra_add_rnh(&p, zvrf_id (zvrf), type); - if (type == RNH_NEXTHOP_TYPE) - { - if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) - SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); - else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) - UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); + + for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) { + /* We don't send any nexthops when there's a multipath */ + if (re->nexthop_active_num > 1 + && client->proto != ZEBRA_ROUTE_LDP) { + SET_FLAG(zapi_flags, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(zapi_flags, ZAPI_MESSAGE_IFINDEX); + + stream_putc(s, 1); + if (p->family == AF_INET) { + stream_put_in_addr(s, &dummy_nh.gate.ipv4); + } else if (p->family == AF_INET6) { + stream_write(s, (u_char *)&dummy_nh.gate.ipv6, + 16); + } else { + /* We don't handle anything else now, abort */ + zlog_err( + "%s: Unable to redistribute route of unknown family, %d\n", + __func__, p->family); + return -1; + } + stream_putc(s, 1); + stream_putl(s, 0); /* dummy ifindex */ + break; + } + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) { + SET_FLAG(zapi_flags, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(zapi_flags, ZAPI_MESSAGE_IFINDEX); + if (nhnummark == 0) { + nhnummark = stream_get_endp(s); + stream_putc(s, 1); /* placeholder */ + } + nhnum++; + + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + stream_put_in_addr(s, &nexthop->gate.ipv4); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + /* Only BGP supports IPv4 prefix with IPv6 NH, + * so kill this */ + if (p->family == AF_INET) + stream_put_in_addr(s, + &dummy_nh.gate.ipv4); + else + stream_write( + s, + (u_char *)&nexthop->gate.ipv6, + 16); + break; + default: + if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD + || cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL) { + struct in_addr empty; + memset(&empty, 0, + sizeof(struct in_addr)); + stream_write(s, (u_char *)&empty, + IPV4_MAX_BYTELEN); + } else { + struct in6_addr empty; + memset(&empty, 0, + sizeof(struct in6_addr)); + stream_write(s, (u_char *)&empty, + IPV6_MAX_BYTELEN); + } + } + + /* Interface index. */ + stream_putc(s, 1); + stream_putl(s, nexthop->ifindex); + + /* ldpd needs all nexthops */ + if (client->proto != ZEBRA_ROUTE_LDP) + break; + } } - else if (type == RNH_IMPORT_CHECK_TYPE) - { - if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)) - SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); - else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)) - UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); + + /* Distance */ + SET_FLAG(zapi_flags, ZAPI_MESSAGE_DISTANCE); + stream_putc(s, re->distance); + + /* Metric */ + SET_FLAG(zapi_flags, ZAPI_MESSAGE_METRIC); + stream_putl(s, re->metric); + + /* Tag */ + if (re->tag) { + SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG); + stream_putl(s, re->tag); } - zebra_add_rnh_client(rnh, client, type, zvrf_id (zvrf)); - /* Anything not AF_INET/INET6 has been filtered out above */ - zebra_evaluate_rnh(zvrf_id (zvrf), p.family, 1, type, &p); - } - return 0; + /* MTU */ + SET_FLAG(zapi_flags, ZAPI_MESSAGE_MTU); + stream_putl(s, re->mtu); + + /* write real message flags value */ + stream_putc_at(s, messmark, zapi_flags); + + /* Write next-hop number */ + if (nhnummark) + stream_putc_at(s, nhnummark, nhnum); + + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + return zebra_server_send_message(client); +} + +static int zsend_write_nexthop(struct stream *s, struct nexthop *nexthop) +{ + stream_putc(s, nexthop->type); + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + stream_put_in_addr(s, &nexthop->gate.ipv4); + stream_putl(s, nexthop->ifindex); + break; + case NEXTHOP_TYPE_IPV6: + stream_put(s, &nexthop->gate.ipv6, 16); + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + stream_put(s, &nexthop->gate.ipv6, 16); + stream_putl(s, nexthop->ifindex); + break; + case NEXTHOP_TYPE_IFINDEX: + stream_putl(s, nexthop->ifindex); + break; + default: + /* do nothing */ + break; + } + return 1; } /* Nexthop register */ -static int -zserv_rnh_unregister (struct zserv *client, int sock, u_short length, - rnh_type_t type, struct zebra_vrf *zvrf) -{ - struct rnh *rnh; - struct stream *s; - struct prefix p; - u_short l = 0; - - if (IS_ZEBRA_DEBUG_NHT) - zlog_debug("rnh_unregister msg from client %s: length=%d\n", - zebra_route_string(client->proto), length); - - s = client->ibuf; - - while (l < length) - { - (void)stream_getc(s); //Connected or not. Not used in this function - p.family = stream_getw(s); - p.prefixlen = stream_getc(s); - l += 4; - if (p.family == AF_INET) - { - p.u.prefix4.s_addr = stream_get_ipv4(s); - l += IPV4_MAX_BYTELEN; - } - else if (p.family == AF_INET6) - { - stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); - l += IPV6_MAX_BYTELEN; - } - else - { - zlog_err("rnh_register: Received unknown family type %d\n", - p.family); - return -1; +static int zserv_rnh_register(struct zserv *client, int sock, u_short length, + rnh_type_t type, struct zebra_vrf *zvrf) +{ + struct rnh *rnh; + struct stream *s; + struct prefix p; + u_short l = 0; + u_char flags = 0; + + if (IS_ZEBRA_DEBUG_NHT) + zlog_debug( + "rnh_register msg from client %s: length=%d, type=%s\n", + zebra_route_string(client->proto), length, + (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route"); + + s = client->ibuf; + + client->nh_reg_time = monotime(NULL); + + while (l < length) { + flags = stream_getc(s); + p.family = stream_getw(s); + p.prefixlen = stream_getc(s); + l += 4; + if (p.family == AF_INET) { + p.u.prefix4.s_addr = stream_get_ipv4(s); + l += IPV4_MAX_BYTELEN; + } else if (p.family == AF_INET6) { + stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); + l += IPV6_MAX_BYTELEN; + } else { + zlog_err( + "rnh_register: Received unknown family type %d\n", + p.family); + return -1; + } + rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type); + if (type == RNH_NEXTHOP_TYPE) { + if (flags + && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) + SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); + else if (!flags + && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) + UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); + } else if (type == RNH_IMPORT_CHECK_TYPE) { + if (flags + && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)) + SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); + else if (!flags && CHECK_FLAG(rnh->flags, + ZEBRA_NHT_EXACT_MATCH)) + UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); + } + + zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf)); + /* Anything not AF_INET/INET6 has been filtered out above */ + zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type, &p); } - rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type); - if (rnh) - { - client->nh_dereg_time = monotime(NULL); - zebra_remove_rnh_client(rnh, client, type); + return 0; +} + +/* Nexthop register */ +static int zserv_rnh_unregister(struct zserv *client, int sock, u_short length, + rnh_type_t type, struct zebra_vrf *zvrf) +{ + struct rnh *rnh; + struct stream *s; + struct prefix p; + u_short l = 0; + + if (IS_ZEBRA_DEBUG_NHT) + zlog_debug("rnh_unregister msg from client %s: length=%d\n", + zebra_route_string(client->proto), length); + + s = client->ibuf; + + while (l < length) { + (void)stream_getc( + s); // Connected or not. Not used in this function + p.family = stream_getw(s); + p.prefixlen = stream_getc(s); + l += 4; + if (p.family == AF_INET) { + p.u.prefix4.s_addr = stream_get_ipv4(s); + l += IPV4_MAX_BYTELEN; + } else if (p.family == AF_INET6) { + stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); + l += IPV6_MAX_BYTELEN; + } else { + zlog_err( + "rnh_register: Received unknown family type %d\n", + p.family); + return -1; + } + rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), type); + if (rnh) { + client->nh_dereg_time = monotime(NULL); + zebra_remove_rnh_client(rnh, client, type); + } } - } - return 0; + return 0; } #define ZEBRA_MIN_FEC_LENGTH 5 /* FEC register */ -static int -zserv_fec_register (struct zserv *client, int sock, u_short length) -{ - struct stream *s; - struct zebra_vrf *zvrf; - u_short l = 0; - struct prefix p; - u_int16_t flags; - u_int32_t label_index = MPLS_INVALID_LABEL_INDEX; - - s = client->ibuf; - zvrf = vrf_info_lookup(VRF_DEFAULT); - if (!zvrf) - return 0; // unexpected - - /* - * The minimum amount of data that can be sent for one fec - * registration - */ - if (length < ZEBRA_MIN_FEC_LENGTH) - { - zlog_err ("fec_register: Received a fec register of length %d, it is of insufficient size to properly decode", - length); - return -1; - } - - while (l < length) - { - flags = stream_getw(s); - p.family = stream_getw(s); - if (p.family != AF_INET && - p.family != AF_INET6) - { - zlog_err ("fec_register: Received unknown family type %d\n", - p.family); - return -1; - } - p.prefixlen = stream_getc(s); - l += 5; - stream_get(&p.u.prefix, s, PSIZE(p.prefixlen)); - l += PSIZE(p.prefixlen); - if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) - { - label_index = stream_getl(s); - l += 4; - } - else - label_index = MPLS_INVALID_LABEL_INDEX; - zebra_mpls_fec_register (zvrf, &p, label_index, client); - } - - return 0; +static int zserv_fec_register(struct zserv *client, int sock, u_short length) +{ + struct stream *s; + struct zebra_vrf *zvrf; + u_short l = 0; + struct prefix p; + u_int16_t flags; + u_int32_t label_index = MPLS_INVALID_LABEL_INDEX; + + s = client->ibuf; + zvrf = vrf_info_lookup(VRF_DEFAULT); + if (!zvrf) + return 0; // unexpected + + /* + * The minimum amount of data that can be sent for one fec + * registration + */ + if (length < ZEBRA_MIN_FEC_LENGTH) { + zlog_err( + "fec_register: Received a fec register of length %d, it is of insufficient size to properly decode", + length); + return -1; + } + + while (l < length) { + flags = stream_getw(s); + p.family = stream_getw(s); + if (p.family != AF_INET && p.family != AF_INET6) { + zlog_err( + "fec_register: Received unknown family type %d\n", + p.family); + return -1; + } + p.prefixlen = stream_getc(s); + l += 5; + stream_get(&p.u.prefix, s, PSIZE(p.prefixlen)); + l += PSIZE(p.prefixlen); + if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) { + label_index = stream_getl(s); + l += 4; + } else + label_index = MPLS_INVALID_LABEL_INDEX; + zebra_mpls_fec_register(zvrf, &p, label_index, client); + } + + return 0; } /* FEC unregister */ -static int -zserv_fec_unregister (struct zserv *client, int sock, u_short length) -{ - struct stream *s; - struct zebra_vrf *zvrf; - u_short l = 0; - struct prefix p; - //u_int16_t flags; - - s = client->ibuf; - zvrf = vrf_info_lookup(VRF_DEFAULT); - if (!zvrf) - return 0; // unexpected - - /* - * The minimum amount of data that can be sent for one - * fec unregistration - */ - if (length < ZEBRA_MIN_FEC_LENGTH) - { - zlog_err ("fec_unregister: Received a fec unregister of length %d, it is of insufficient size to properly decode", - length); - return -1; - } - - while (l < length) - { - //flags = stream_getw(s); - (void)stream_getw(s); - p.family = stream_getw(s); - if (p.family != AF_INET && - p.family != AF_INET6) - { - zlog_err ("fec_unregister: Received unknown family type %d\n", - p.family); - return -1; - } - p.prefixlen = stream_getc(s); - l += 5; - stream_get(&p.u.prefix, s, PSIZE(p.prefixlen)); - l += PSIZE(p.prefixlen); - zebra_mpls_fec_unregister (zvrf, &p, client); - } - - return 0; +static int zserv_fec_unregister(struct zserv *client, int sock, u_short length) +{ + struct stream *s; + struct zebra_vrf *zvrf; + u_short l = 0; + struct prefix p; + // u_int16_t flags; + + s = client->ibuf; + zvrf = vrf_info_lookup(VRF_DEFAULT); + if (!zvrf) + return 0; // unexpected + + /* + * The minimum amount of data that can be sent for one + * fec unregistration + */ + if (length < ZEBRA_MIN_FEC_LENGTH) { + zlog_err( + "fec_unregister: Received a fec unregister of length %d, it is of insufficient size to properly decode", + length); + return -1; + } + + while (l < length) { + // flags = stream_getw(s); + (void)stream_getw(s); + p.family = stream_getw(s); + if (p.family != AF_INET && p.family != AF_INET6) { + zlog_err( + "fec_unregister: Received unknown family type %d\n", + p.family); + return -1; + } + p.prefixlen = stream_getc(s); + l += 5; + stream_get(&p.u.prefix, s, PSIZE(p.prefixlen)); + l += PSIZE(p.prefixlen); + zebra_mpls_fec_unregister(zvrf, &p, client); + } + + return 0; } /* @@ -1051,1514 +1010,1510 @@ zserv_fec_unregister (struct zserv *client, int sock, u_short length) Query unicast rib if nexthop is not found on mrib. Returns both route metric and protocol distance. */ -static int -zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struct route_entry *re, struct zebra_vrf *zvrf) -{ - struct stream *s; - unsigned long nump; - u_char num; - struct nexthop *nexthop; - - /* Get output stream. */ - s = client->obuf; - stream_reset (s); - - /* Fill in result. */ - zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id (zvrf)); - stream_put_in_addr (s, &addr); - - if (re) - { - stream_putc (s, re->distance); - stream_putl (s, re->metric); - num = 0; - nump = stream_get_endp(s); /* remember position for nexthop_num */ - stream_putc (s, 0); /* reserve room for nexthop_num */ - /* Only non-recursive routes are elegible to resolve the nexthop we - * are looking up. Therefore, we will just iterate over the top - * chain of nexthops. */ - for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - num += zsend_write_nexthop (s, nexthop); - - stream_putc_at (s, nump, num); /* store nexthop_num */ - } - else - { - stream_putc (s, 0); /* distance */ - stream_putl (s, 0); /* metric */ - stream_putc (s, 0); /* nexthop_num */ - } - - stream_putw_at (s, 0, stream_get_endp (s)); - - return zebra_server_send_message(client); +static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client, + struct in_addr addr, + struct route_entry *re, + struct zebra_vrf *zvrf) +{ + struct stream *s; + unsigned long nump; + u_char num; + struct nexthop *nexthop; + + /* Get output stream. */ + s = client->obuf; + stream_reset(s); + + /* Fill in result. */ + zserv_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id(zvrf)); + stream_put_in_addr(s, &addr); + + if (re) { + stream_putc(s, re->distance); + stream_putl(s, re->metric); + num = 0; + nump = stream_get_endp( + s); /* remember position for nexthop_num */ + stream_putc(s, 0); /* reserve room for nexthop_num */ + /* Only non-recursive routes are elegible to resolve the nexthop + * we + * are looking up. Therefore, we will just iterate over the top + * chain of nexthops. */ + for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + num += zsend_write_nexthop(s, nexthop); + + stream_putc_at(s, nump, num); /* store nexthop_num */ + } else { + stream_putc(s, 0); /* distance */ + stream_putl(s, 0); /* metric */ + stream_putc(s, 0); /* nexthop_num */ + } + + stream_putw_at(s, 0, stream_get_endp(s)); + + return zebra_server_send_message(client); } /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */ -int -zsend_router_id_update (struct zserv *client, struct prefix *p, - vrf_id_t vrf_id) +int zsend_router_id_update(struct zserv *client, struct prefix *p, + vrf_id_t vrf_id) { - struct stream *s; - int blen; + struct stream *s; + int blen; - /* Check this client need interface information. */ - if (! vrf_bitmap_check (client->ridinfo, vrf_id)) - return 0; + /* Check this client need interface information. */ + if (!vrf_bitmap_check(client->ridinfo, vrf_id)) + return 0; - s = client->obuf; - stream_reset (s); + s = client->obuf; + stream_reset(s); - /* Message type. */ - zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id); + /* Message type. */ + zserv_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id); - /* Prefix information. */ - stream_putc (s, p->family); - blen = prefix_blen (p); - stream_put (s, &p->u.prefix, blen); - stream_putc (s, p->prefixlen); + /* Prefix information. */ + stream_putc(s, p->family); + blen = prefix_blen(p); + stream_put(s, &p->u.prefix, blen); + stream_putc(s, p->prefixlen); - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); - return zebra_server_send_message(client); + return zebra_server_send_message(client); } /* Register zebra server interface information. Send current all interface and address information. */ -static int -zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_interface_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { - struct vrf *vrf; - struct listnode *ifnode, *ifnnode; - struct interface *ifp; + struct vrf *vrf; + struct listnode *ifnode, *ifnnode; + struct interface *ifp; - /* Interface information is needed. */ - vrf_bitmap_set (client->ifinfo, zvrf_id (zvrf)); + /* Interface information is needed. */ + vrf_bitmap_set(client->ifinfo, zvrf_id(zvrf)); - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - { - for (ALL_LIST_ELEMENTS (vrf->iflist, ifnode, ifnnode, ifp)) - { - /* Skip pseudo interface. */ - if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) - continue; + RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) + { + for (ALL_LIST_ELEMENTS(vrf->iflist, ifnode, ifnnode, ifp)) { + /* Skip pseudo interface. */ + if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) + continue; - if (zsend_interface_add (client, ifp) < 0) - return -1; + if (zsend_interface_add(client, ifp) < 0) + return -1; - if (zsend_interface_addresses (client, ifp) < 0) - return -1; - } - } - return 0; + if (zsend_interface_addresses(client, ifp) < 0) + return -1; + } + } + return 0; } /* Unregister zebra server interface information. */ -static int -zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_interface_delete(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { - vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf)); - return 0; + vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf)); + return 0; } -void -zserv_nexthop_num_warn (const char *caller, const struct prefix *p, const unsigned int nexthop_num) +void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, + const unsigned int nexthop_num) { - if (nexthop_num > multipath_num) - { - char buff[PREFIX2STR_BUFFER]; - prefix2str(p, buff, sizeof (buff)); - zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d", - caller, buff, nexthop_num, multipath_num); - } + if (nexthop_num > multipath_num) { + char buff[PREFIX2STR_BUFFER]; + prefix2str(p, buff, sizeof(buff)); + zlog_warn( + "%s: Prefix %s has %d nexthops, but we can only use the first %d", + caller, buff, nexthop_num, multipath_num); + } } /* This function support multiple nexthop. */ -/* +/* * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update re and - * add kernel route. + * add kernel route. */ -static int -zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ - int i; - struct route_entry *re; - struct prefix p; - u_char message; - struct in_addr nhop_addr; - u_char nexthop_num; - u_char nexthop_type; - struct stream *s; - ifindex_t ifindex; - safi_t safi; - int ret; - mpls_label_t label; - struct nexthop *nexthop; - - /* Get input stream. */ - s = client->ibuf; - - /* Allocate new re. */ - re = XCALLOC (MTYPE_RE, sizeof (struct route_entry)); - - /* Type, flags, message. */ - re->type = stream_getc (s); - re->instance = stream_getw (s); - re->flags = stream_getl (s); - message = stream_getc (s); - safi = stream_getw (s); - re->uptime = time (NULL); - - /* IPv4 prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = stream_getc (s); - stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); - - /* VRF ID */ - re->vrf_id = zvrf_id (zvrf); - - /* Nexthop parse. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) - { - nexthop_num = stream_getc (s); - zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num); - - for (i = 0; i < nexthop_num; i++) - { - nexthop_type = stream_getc (s); - - switch (nexthop_type) - { - case NEXTHOP_TYPE_IFINDEX: - ifindex = stream_getl (s); - route_entry_nexthop_ifindex_add (re, ifindex); - break; - case NEXTHOP_TYPE_IPV4: - nhop_addr.s_addr = stream_get_ipv4 (s); - nexthop = route_entry_nexthop_ipv4_add (re, &nhop_addr, NULL); - /* For labeled-unicast, each nexthop is followed by label. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL)) - { - label = (mpls_label_t)stream_getl (s); - nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &label); - } - break; - case NEXTHOP_TYPE_IPV4_IFINDEX: - nhop_addr.s_addr = stream_get_ipv4 (s); - ifindex = stream_getl (s); - route_entry_nexthop_ipv4_ifindex_add (re, &nhop_addr, NULL, ifindex); - break; - case NEXTHOP_TYPE_IPV6: - stream_forward_getp (s, IPV6_MAX_BYTELEN); - break; - case NEXTHOP_TYPE_BLACKHOLE: - route_entry_nexthop_blackhole_add (re); - break; - } +static int zread_ipv4_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) +{ + int i; + struct route_entry *re; + struct prefix p; + u_char message; + struct in_addr nhop_addr; + u_char nexthop_num; + u_char nexthop_type; + struct stream *s; + ifindex_t ifindex; + safi_t safi; + int ret; + mpls_label_t label; + struct nexthop *nexthop; + + /* Get input stream. */ + s = client->ibuf; + + /* Allocate new re. */ + re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); + + /* Type, flags, message. */ + re->type = stream_getc(s); + re->instance = stream_getw(s); + re->flags = stream_getl(s); + message = stream_getc(s); + safi = stream_getw(s); + re->uptime = time(NULL); + + /* IPv4 prefix. */ + memset(&p, 0, sizeof(struct prefix_ipv4)); + p.family = AF_INET; + p.prefixlen = stream_getc(s); + stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); + + /* VRF ID */ + re->vrf_id = zvrf_id(zvrf); + + /* Nexthop parse. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { + nexthop_num = stream_getc(s); + zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, + nexthop_num); + + for (i = 0; i < nexthop_num; i++) { + nexthop_type = stream_getc(s); + + switch (nexthop_type) { + case NEXTHOP_TYPE_IFINDEX: + ifindex = stream_getl(s); + route_entry_nexthop_ifindex_add(re, ifindex); + break; + case NEXTHOP_TYPE_IPV4: + nhop_addr.s_addr = stream_get_ipv4(s); + nexthop = route_entry_nexthop_ipv4_add( + re, &nhop_addr, NULL); + /* For labeled-unicast, each nexthop is followed + * by label. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) { + label = (mpls_label_t)stream_getl(s); + nexthop_add_labels( + nexthop, nexthop->nh_label_type, + 1, &label); + } + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + nhop_addr.s_addr = stream_get_ipv4(s); + ifindex = stream_getl(s); + route_entry_nexthop_ipv4_ifindex_add( + re, &nhop_addr, NULL, ifindex); + break; + case NEXTHOP_TYPE_IPV6: + stream_forward_getp(s, IPV6_MAX_BYTELEN); + break; + case NEXTHOP_TYPE_BLACKHOLE: + route_entry_nexthop_blackhole_add(re); + break; + } + } } - } - /* Distance. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) - re->distance = stream_getc (s); + /* Distance. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) + re->distance = stream_getc(s); - /* Metric. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) - re->metric = stream_getl (s); - - /* Tag */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) - re->tag = stream_getl (s); - else - re->tag = 0; + /* Metric. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) + re->metric = stream_getl(s); - if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) - re->mtu = stream_getl (s); - else - re->mtu = 0; + /* Tag */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) + re->tag = stream_getl(s); + else + re->tag = 0; - /* Table */ - re->table = zvrf->table_id; + if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU)) + re->mtu = stream_getl(s); + else + re->mtu = 0; + + /* Table */ + re->table = zvrf->table_id; - ret = rib_add_multipath (AFI_IP, safi, &p, NULL, re); + ret = rib_add_multipath(AFI_IP, safi, &p, NULL, re); - /* Stats */ - if (ret > 0) - client->v4_route_add_cnt++; - else if (ret < 0) - client->v4_route_upd8_cnt++; - return 0; + /* Stats */ + if (ret > 0) + client->v4_route_add_cnt++; + else if (ret < 0) + client->v4_route_upd8_cnt++; + return 0; } /* Zebra server IPv4 prefix delete function. */ -static int -zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ - int i; - struct stream *s; - struct zapi_ipv4 api; - struct in_addr nexthop; - union g_addr *nexthop_p; - unsigned long ifindex; - struct prefix p; - u_char nexthop_num; - u_char nexthop_type; - u_int32_t table_id; - - s = client->ibuf; - ifindex = 0; - nexthop.s_addr = 0; - nexthop_p = NULL; - - /* Type, flags, message. */ - api.type = stream_getc (s); - api.instance = stream_getw (s); - api.flags = stream_getl (s); - api.message = stream_getc (s); - api.safi = stream_getw (s); - - /* IPv4 prefix. */ - memset (&p, 0, sizeof (struct prefix)); - p.family = AF_INET; - p.prefixlen = stream_getc (s); - stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) - { - nexthop_num = stream_getc (s); - - for (i = 0; i < nexthop_num; i++) - { - nexthop_type = stream_getc (s); - - switch (nexthop_type) - { - case NEXTHOP_TYPE_IFINDEX: - ifindex = stream_getl (s); - break; - case NEXTHOP_TYPE_IPV4: - nexthop.s_addr = stream_get_ipv4 (s); - /* For labeled-unicast, each nexthop is followed by label, but - * we don't care for delete. - */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_LABEL)) - stream_forward_getp (s, sizeof(u_int32_t)); - nexthop_p = (union g_addr *)&nexthop; - break; - case NEXTHOP_TYPE_IPV4_IFINDEX: - nexthop.s_addr = stream_get_ipv4 (s); - nexthop_p = (union g_addr *)&nexthop; - ifindex = stream_getl (s); - break; - case NEXTHOP_TYPE_IPV6: - stream_forward_getp (s, IPV6_MAX_BYTELEN); - break; - } +static int zread_ipv4_delete(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) +{ + int i; + struct stream *s; + struct zapi_ipv4 api; + struct in_addr nexthop; + union g_addr *nexthop_p; + unsigned long ifindex; + struct prefix p; + u_char nexthop_num; + u_char nexthop_type; + u_int32_t table_id; + + s = client->ibuf; + ifindex = 0; + nexthop.s_addr = 0; + nexthop_p = NULL; + + /* Type, flags, message. */ + api.type = stream_getc(s); + api.instance = stream_getw(s); + api.flags = stream_getl(s); + api.message = stream_getc(s); + api.safi = stream_getw(s); + + /* IPv4 prefix. */ + memset(&p, 0, sizeof(struct prefix)); + p.family = AF_INET; + p.prefixlen = stream_getc(s); + stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); + + /* Nexthop, ifindex, distance, metric. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + nexthop_num = stream_getc(s); + + for (i = 0; i < nexthop_num; i++) { + nexthop_type = stream_getc(s); + + switch (nexthop_type) { + case NEXTHOP_TYPE_IFINDEX: + ifindex = stream_getl(s); + break; + case NEXTHOP_TYPE_IPV4: + nexthop.s_addr = stream_get_ipv4(s); + /* For labeled-unicast, each nexthop is followed + * by label, but + * we don't care for delete. + */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)) + stream_forward_getp(s, + sizeof(u_int32_t)); + nexthop_p = (union g_addr *)&nexthop; + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + nexthop.s_addr = stream_get_ipv4(s); + nexthop_p = (union g_addr *)&nexthop; + ifindex = stream_getl(s); + break; + case NEXTHOP_TYPE_IPV6: + stream_forward_getp(s, IPV6_MAX_BYTELEN); + break; + } + } } - } - - /* Distance. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc (s); - else - api.distance = 0; - - /* Metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl (s); - else - api.metric = 0; - - /* tag */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl (s); - else - api.tag = 0; - - table_id = zvrf->table_id; - - rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance, - api.flags, &p, NULL, nexthop_p, ifindex, table_id); - client->v4_route_del_cnt++; - return 0; + + /* Distance. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) + api.distance = stream_getc(s); + else + api.distance = 0; + + /* Metric. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) + api.metric = stream_getl(s); + else + api.metric = 0; + + /* tag */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) + api.tag = stream_getl(s); + else + api.tag = 0; + + table_id = zvrf->table_id; + + rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance, + api.flags, &p, NULL, nexthop_p, ifindex, table_id); + client->v4_route_del_cnt++; + return 0; } /* MRIB Nexthop lookup for IPv4. */ -static int -zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_ipv4_nexthop_lookup_mrib(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { - struct in_addr addr; - struct route_entry *re; + struct in_addr addr; + struct route_entry *re; - addr.s_addr = stream_get_ipv4 (client->ibuf); - re = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL); - return zsend_ipv4_nexthop_lookup_mrib (client, addr, re, zvrf); + addr.s_addr = stream_get_ipv4(client->ibuf); + re = rib_match_ipv4_multicast(zvrf_id(zvrf), addr, NULL); + return zsend_ipv4_nexthop_lookup_mrib(client, addr, re, zvrf); } /* Zebra server IPv6 prefix add function. */ -static int -zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ - unsigned int i; - struct stream *s; - struct in6_addr nhop_addr; - struct route_entry *re; - u_char message; - u_char nexthop_num; - u_char nexthop_type; - struct prefix p; - safi_t safi; - static struct in6_addr nexthops[MULTIPATH_NUM]; - static unsigned int ifindices[MULTIPATH_NUM]; - int ret; - static mpls_label_t labels[MULTIPATH_NUM]; - mpls_label_t label; - struct nexthop *nexthop; - - /* Get input stream. */ - s = client->ibuf; - - memset (&nhop_addr, 0, sizeof (struct in6_addr)); - - /* Allocate new re. */ - re = XCALLOC (MTYPE_RE, sizeof (struct route_entry)); - - /* Type, flags, message. */ - re->type = stream_getc (s); - re->instance = stream_getw (s); - re->flags = stream_getl (s); - message = stream_getc (s); - safi = stream_getw (s); - re->uptime = time (NULL); - - /* IPv4 prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv4)); - p.family = AF_INET; - p.prefixlen = stream_getc (s); - stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); - - /* VRF ID */ - re->vrf_id = zvrf_id (zvrf); - - /* We need to give nh-addr, nh-ifindex with the same next-hop object - * to the re to ensure that IPv6 multipathing works; need to coalesce - * these. Clients should send the same number of paired set of - * next-hop-addr/next-hop-ifindices. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) - { - unsigned int nh_count = 0; - unsigned int if_count = 0; - unsigned int max_nh_if = 0; - - nexthop_num = stream_getc (s); - zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num); - for (i = 0; i < nexthop_num; i++) - { - nexthop_type = stream_getc (s); - - switch (nexthop_type) - { - case NEXTHOP_TYPE_IPV6: - stream_get (&nhop_addr, s, 16); - if (nh_count < MULTIPATH_NUM) - { - /* For labeled-unicast, each nexthop is followed by label. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL)) - { - label = (mpls_label_t)stream_getl (s); - labels[nh_count] = label; - } - nexthops[nh_count] = nhop_addr; - nh_count++; - } - break; - case NEXTHOP_TYPE_IFINDEX: - if (if_count < multipath_num) { - ifindices[if_count++] = stream_getl (s); - } - break; - case NEXTHOP_TYPE_BLACKHOLE: - route_entry_nexthop_blackhole_add (re); - break; - } +static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, + u_short length, + struct zebra_vrf *zvrf) +{ + unsigned int i; + struct stream *s; + struct in6_addr nhop_addr; + struct route_entry *re; + u_char message; + u_char nexthop_num; + u_char nexthop_type; + struct prefix p; + safi_t safi; + static struct in6_addr nexthops[MULTIPATH_NUM]; + static unsigned int ifindices[MULTIPATH_NUM]; + int ret; + static mpls_label_t labels[MULTIPATH_NUM]; + mpls_label_t label; + struct nexthop *nexthop; + + /* Get input stream. */ + s = client->ibuf; + + memset(&nhop_addr, 0, sizeof(struct in6_addr)); + + /* Allocate new re. */ + re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); + + /* Type, flags, message. */ + re->type = stream_getc(s); + re->instance = stream_getw(s); + re->flags = stream_getl(s); + message = stream_getc(s); + safi = stream_getw(s); + re->uptime = time(NULL); + + /* IPv4 prefix. */ + memset(&p, 0, sizeof(struct prefix_ipv4)); + p.family = AF_INET; + p.prefixlen = stream_getc(s); + stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); + + /* VRF ID */ + re->vrf_id = zvrf_id(zvrf); + + /* We need to give nh-addr, nh-ifindex with the same next-hop object + * to the re to ensure that IPv6 multipathing works; need to coalesce + * these. Clients should send the same number of paired set of + * next-hop-addr/next-hop-ifindices. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { + unsigned int nh_count = 0; + unsigned int if_count = 0; + unsigned int max_nh_if = 0; + + nexthop_num = stream_getc(s); + zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, + nexthop_num); + for (i = 0; i < nexthop_num; i++) { + nexthop_type = stream_getc(s); + + switch (nexthop_type) { + case NEXTHOP_TYPE_IPV6: + stream_get(&nhop_addr, s, 16); + if (nh_count < MULTIPATH_NUM) { + /* For labeled-unicast, each nexthop is + * followed by label. */ + if (CHECK_FLAG(message, + ZAPI_MESSAGE_LABEL)) { + label = (mpls_label_t) + stream_getl(s); + labels[nh_count] = label; + } + nexthops[nh_count] = nhop_addr; + nh_count++; + } + break; + case NEXTHOP_TYPE_IFINDEX: + if (if_count < multipath_num) { + ifindices[if_count++] = stream_getl(s); + } + break; + case NEXTHOP_TYPE_BLACKHOLE: + route_entry_nexthop_blackhole_add(re); + break; + } + } + + max_nh_if = (nh_count > if_count) ? nh_count : if_count; + for (i = 0; i < max_nh_if; i++) { + if ((i < nh_count) + && !IN6_IS_ADDR_UNSPECIFIED(&nexthops[i])) { + if ((i < if_count) && ifindices[i]) + nexthop = + route_entry_nexthop_ipv6_ifindex_add( + re, &nexthops[i], + ifindices[i]); + else + nexthop = route_entry_nexthop_ipv6_add( + re, &nexthops[i]); + + if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) + nexthop_add_labels( + nexthop, nexthop->nh_label_type, + 1, &labels[i]); + } else { + if ((i < if_count) && ifindices[i]) + route_entry_nexthop_ifindex_add( + re, ifindices[i]); + } + } } - max_nh_if = (nh_count > if_count) ? nh_count : if_count; - for (i = 0; i < max_nh_if; i++) - { - if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) { - if ((i < if_count) && ifindices[i]) - nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &nexthops[i], ifindices[i]); - else - nexthop = route_entry_nexthop_ipv6_add (re, &nexthops[i]); - - if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL)) - nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]); - } - else { - if ((i < if_count) && ifindices[i]) - route_entry_nexthop_ifindex_add (re, ifindices[i]); - } - } - } - - /* Distance. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) - re->distance = stream_getc (s); - - /* Metric. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) - re->metric = stream_getl (s); - - /* Tag */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) - re->tag = stream_getl (s); - else - re->tag = 0; - - if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) - re->mtu = stream_getl (s); - else - re->mtu = 0; - - /* Table */ - re->table = zvrf->table_id; - - ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, re); - /* Stats */ - if (ret > 0) - client->v4_route_add_cnt++; - else if (ret < 0) - client->v4_route_upd8_cnt++; - - return 0; -} - -static int -zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ - unsigned int i; - struct stream *s; - struct in6_addr nhop_addr; - struct route_entry *re; - u_char message; - u_char nexthop_num; - u_char nexthop_type; - struct prefix p; - struct prefix_ipv6 src_p, *src_pp; - safi_t safi; - static struct in6_addr nexthops[MULTIPATH_NUM]; - static unsigned int ifindices[MULTIPATH_NUM]; - int ret; - static mpls_label_t labels[MULTIPATH_NUM]; - mpls_label_t label; - struct nexthop *nexthop; - - /* Get input stream. */ - s = client->ibuf; - - memset (&nhop_addr, 0, sizeof (struct in6_addr)); - - /* Allocate new re. */ - re = XCALLOC (MTYPE_RE, sizeof (struct route_entry)); - - /* Type, flags, message. */ - re->type = stream_getc (s); - re->instance = stream_getw (s); - re->flags = stream_getl (s); - message = stream_getc (s); - safi = stream_getw (s); - re->uptime = time (NULL); - - /* IPv6 prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = stream_getc (s); - stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen)); - - if (CHECK_FLAG (message, ZAPI_MESSAGE_SRCPFX)) - { - memset (&src_p, 0, sizeof (struct prefix_ipv6)); - src_p.family = AF_INET6; - src_p.prefixlen = stream_getc (s); - stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen)); - src_pp = &src_p; - } - else - src_pp = NULL; - - /* We need to give nh-addr, nh-ifindex with the same next-hop object - * to the re to ensure that IPv6 multipathing works; need to coalesce - * these. Clients should send the same number of paired set of - * next-hop-addr/next-hop-ifindices. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) - { - unsigned int nh_count = 0; - unsigned int if_count = 0; - unsigned int max_nh_if = 0; - - nexthop_num = stream_getc (s); - zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num); - for (i = 0; i < nexthop_num; i++) - { - nexthop_type = stream_getc (s); - - switch (nexthop_type) - { - case NEXTHOP_TYPE_IPV6: - stream_get (&nhop_addr, s, 16); - if (nh_count < MULTIPATH_NUM) - { - /* For labeled-unicast, each nexthop is followed by label. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL)) - { - label = (mpls_label_t)stream_getl (s); - labels[nh_count] = label; - } - nexthops[nh_count++] = nhop_addr; - } - break; - case NEXTHOP_TYPE_IFINDEX: - if (if_count < multipath_num) { - ifindices[if_count++] = stream_getl (s); - } - break; - case NEXTHOP_TYPE_BLACKHOLE: - route_entry_nexthop_blackhole_add (re); - break; - } - } + /* Distance. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) + re->distance = stream_getc(s); - max_nh_if = (nh_count > if_count) ? nh_count : if_count; - for (i = 0; i < max_nh_if; i++) - { - if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) { - if ((i < if_count) && ifindices[i]) - nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &nexthops[i], ifindices[i]); - else - nexthop = route_entry_nexthop_ipv6_add (re, &nexthops[i]); - if (CHECK_FLAG (message, ZAPI_MESSAGE_LABEL)) - nexthop_add_labels (nexthop, nexthop->nh_label_type, 1, &labels[i]); - } - else { - if ((i < if_count) && ifindices[i]) - route_entry_nexthop_ifindex_add (re, ifindices[i]); - } + /* Metric. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) + re->metric = stream_getl(s); + + /* Tag */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) + re->tag = stream_getl(s); + else + re->tag = 0; + + if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU)) + re->mtu = stream_getl(s); + else + re->mtu = 0; + + /* Table */ + re->table = zvrf->table_id; + + ret = rib_add_multipath(AFI_IP6, safi, &p, NULL, re); + /* Stats */ + if (ret > 0) + client->v4_route_add_cnt++; + else if (ret < 0) + client->v4_route_upd8_cnt++; + + return 0; +} + +static int zread_ipv6_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) +{ + unsigned int i; + struct stream *s; + struct in6_addr nhop_addr; + struct route_entry *re; + u_char message; + u_char nexthop_num; + u_char nexthop_type; + struct prefix p; + struct prefix_ipv6 src_p, *src_pp; + safi_t safi; + static struct in6_addr nexthops[MULTIPATH_NUM]; + static unsigned int ifindices[MULTIPATH_NUM]; + int ret; + static mpls_label_t labels[MULTIPATH_NUM]; + mpls_label_t label; + struct nexthop *nexthop; + + /* Get input stream. */ + s = client->ibuf; + + memset(&nhop_addr, 0, sizeof(struct in6_addr)); + + /* Allocate new re. */ + re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); + + /* Type, flags, message. */ + re->type = stream_getc(s); + re->instance = stream_getw(s); + re->flags = stream_getl(s); + message = stream_getc(s); + safi = stream_getw(s); + re->uptime = time(NULL); + + /* IPv6 prefix. */ + memset(&p, 0, sizeof(struct prefix_ipv6)); + p.family = AF_INET6; + p.prefixlen = stream_getc(s); + stream_get(&p.u.prefix6, s, PSIZE(p.prefixlen)); + + if (CHECK_FLAG(message, ZAPI_MESSAGE_SRCPFX)) { + memset(&src_p, 0, sizeof(struct prefix_ipv6)); + src_p.family = AF_INET6; + src_p.prefixlen = stream_getc(s); + stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); + src_pp = &src_p; + } else + src_pp = NULL; + + /* We need to give nh-addr, nh-ifindex with the same next-hop object + * to the re to ensure that IPv6 multipathing works; need to coalesce + * these. Clients should send the same number of paired set of + * next-hop-addr/next-hop-ifindices. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { + unsigned int nh_count = 0; + unsigned int if_count = 0; + unsigned int max_nh_if = 0; + + nexthop_num = stream_getc(s); + zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, + nexthop_num); + for (i = 0; i < nexthop_num; i++) { + nexthop_type = stream_getc(s); + + switch (nexthop_type) { + case NEXTHOP_TYPE_IPV6: + stream_get(&nhop_addr, s, 16); + if (nh_count < MULTIPATH_NUM) { + /* For labeled-unicast, each nexthop is + * followed by label. */ + if (CHECK_FLAG(message, + ZAPI_MESSAGE_LABEL)) { + label = (mpls_label_t) + stream_getl(s); + labels[nh_count] = label; + } + nexthops[nh_count++] = nhop_addr; + } + break; + case NEXTHOP_TYPE_IFINDEX: + if (if_count < multipath_num) { + ifindices[if_count++] = stream_getl(s); + } + break; + case NEXTHOP_TYPE_BLACKHOLE: + route_entry_nexthop_blackhole_add(re); + break; + } + } + + max_nh_if = (nh_count > if_count) ? nh_count : if_count; + for (i = 0; i < max_nh_if; i++) { + if ((i < nh_count) + && !IN6_IS_ADDR_UNSPECIFIED(&nexthops[i])) { + if ((i < if_count) && ifindices[i]) + nexthop = + route_entry_nexthop_ipv6_ifindex_add( + re, &nexthops[i], + ifindices[i]); + else + nexthop = route_entry_nexthop_ipv6_add( + re, &nexthops[i]); + if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) + nexthop_add_labels( + nexthop, nexthop->nh_label_type, + 1, &labels[i]); + } else { + if ((i < if_count) && ifindices[i]) + route_entry_nexthop_ifindex_add( + re, ifindices[i]); + } + } } - } - /* Distance. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) - re->distance = stream_getc (s); + /* Distance. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) + re->distance = stream_getc(s); + + /* Metric. */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) + re->metric = stream_getl(s); - /* Metric. */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) - re->metric = stream_getl (s); - - /* Tag */ - if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) - re->tag = stream_getl (s); - else - re->tag = 0; + /* Tag */ + if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) + re->tag = stream_getl(s); + else + re->tag = 0; - if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) - re->mtu = stream_getl (s); - else - re->mtu = 0; + if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU)) + re->mtu = stream_getl(s); + else + re->mtu = 0; - /* VRF ID */ - re->vrf_id = zvrf_id (zvrf); - re->table = zvrf->table_id; + /* VRF ID */ + re->vrf_id = zvrf_id(zvrf); + re->table = zvrf->table_id; - ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, re); - /* Stats */ - if (ret > 0) - client->v6_route_add_cnt++; - else if (ret < 0) - client->v6_route_upd8_cnt++; + ret = rib_add_multipath(AFI_IP6, safi, &p, src_pp, re); + /* Stats */ + if (ret > 0) + client->v6_route_add_cnt++; + else if (ret < 0) + client->v6_route_upd8_cnt++; - return 0; + return 0; } /* Zebra server IPv6 prefix delete function. */ -static int -zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ - int i; - struct stream *s; - struct zapi_ipv6 api; - struct in6_addr nexthop; - union g_addr *pnexthop = NULL; - unsigned long ifindex; - struct prefix p; - struct prefix_ipv6 src_p, *src_pp; - - s = client->ibuf; - ifindex = 0; - memset (&nexthop, 0, sizeof (struct in6_addr)); - - /* Type, flags, message. */ - api.type = stream_getc (s); - api.instance = stream_getw (s); - api.flags = stream_getl (s); - api.message = stream_getc (s); - api.safi = stream_getw (s); - - /* IPv4 prefix. */ - memset (&p, 0, sizeof (struct prefix_ipv6)); - p.family = AF_INET6; - p.prefixlen = stream_getc (s); - stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen)); - - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX)) - { - memset (&src_p, 0, sizeof (struct prefix_ipv6)); - src_p.family = AF_INET6; - src_p.prefixlen = stream_getc (s); - stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen)); - src_pp = &src_p; - } - else - src_pp = NULL; - - /* Nexthop, ifindex, distance, metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) - { - u_char nexthop_type; - - api.nexthop_num = stream_getc (s); - for (i = 0; i < api.nexthop_num; i++) - { - nexthop_type = stream_getc (s); - - switch (nexthop_type) - { - case NEXTHOP_TYPE_IPV6: - stream_get (&nexthop, s, 16); - /* For labeled-unicast, each nexthop is followed by label, but - * we don't care for delete. - */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_LABEL)) - stream_forward_getp (s, sizeof(u_int32_t)); - pnexthop = (union g_addr *)&nexthop; - break; - case NEXTHOP_TYPE_IFINDEX: - ifindex = stream_getl (s); - break; - } +static int zread_ipv6_delete(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) +{ + int i; + struct stream *s; + struct zapi_ipv6 api; + struct in6_addr nexthop; + union g_addr *pnexthop = NULL; + unsigned long ifindex; + struct prefix p; + struct prefix_ipv6 src_p, *src_pp; + + s = client->ibuf; + ifindex = 0; + memset(&nexthop, 0, sizeof(struct in6_addr)); + + /* Type, flags, message. */ + api.type = stream_getc(s); + api.instance = stream_getw(s); + api.flags = stream_getl(s); + api.message = stream_getc(s); + api.safi = stream_getw(s); + + /* IPv4 prefix. */ + memset(&p, 0, sizeof(struct prefix_ipv6)); + p.family = AF_INET6; + p.prefixlen = stream_getc(s); + stream_get(&p.u.prefix6, s, PSIZE(p.prefixlen)); + + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { + memset(&src_p, 0, sizeof(struct prefix_ipv6)); + src_p.family = AF_INET6; + src_p.prefixlen = stream_getc(s); + stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); + src_pp = &src_p; + } else + src_pp = NULL; + + /* Nexthop, ifindex, distance, metric. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { + u_char nexthop_type; + + api.nexthop_num = stream_getc(s); + for (i = 0; i < api.nexthop_num; i++) { + nexthop_type = stream_getc(s); + + switch (nexthop_type) { + case NEXTHOP_TYPE_IPV6: + stream_get(&nexthop, s, 16); + /* For labeled-unicast, each nexthop is followed + * by label, but + * we don't care for delete. + */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)) + stream_forward_getp(s, + sizeof(u_int32_t)); + pnexthop = (union g_addr *)&nexthop; + break; + case NEXTHOP_TYPE_IFINDEX: + ifindex = stream_getl(s); + break; + } + } } - } - - /* Distance. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) - api.distance = stream_getc (s); - else - api.distance = 0; - - /* Metric. */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) - api.metric = stream_getl (s); - else - api.metric = 0; - - /* tag */ - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG)) - api.tag = stream_getl (s); - else - api.tag = 0; - - if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) - rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, - api.flags, &p, src_pp, NULL, ifindex, client->rtm_table); - else - rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, - api.flags, &p, src_pp, pnexthop, ifindex, client->rtm_table); - - client->v6_route_del_cnt++; - return 0; + + /* Distance. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) + api.distance = stream_getc(s); + else + api.distance = 0; + + /* Metric. */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) + api.metric = stream_getl(s); + else + api.metric = 0; + + /* tag */ + if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) + api.tag = stream_getl(s); + else + api.tag = 0; + + if (IN6_IS_ADDR_UNSPECIFIED(&nexthop)) + rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, + api.instance, api.flags, &p, src_pp, NULL, ifindex, + client->rtm_table); + else + rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, + api.instance, api.flags, &p, src_pp, pnexthop, + ifindex, client->rtm_table); + + client->v6_route_del_cnt++; + return 0; } /* Register zebra server router-id information. Send current router-id */ -static int -zread_router_id_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_router_id_add(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { - struct prefix p; + struct prefix p; - /* Router-id information is needed. */ - vrf_bitmap_set (client->ridinfo, zvrf_id (zvrf)); + /* Router-id information is needed. */ + vrf_bitmap_set(client->ridinfo, zvrf_id(zvrf)); - router_id_get (&p, zvrf_id (zvrf)); + router_id_get(&p, zvrf_id(zvrf)); - return zsend_router_id_update (client, &p, zvrf_id (zvrf)); + return zsend_router_id_update(client, &p, zvrf_id(zvrf)); } /* Unregister zebra server router-id information. */ -static int -zread_router_id_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_router_id_delete(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) { - vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf)); - return 0; + vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf)); + return 0; } /* Tie up route-type and client->sock */ -static void -zread_hello (struct zserv *client) +static void zread_hello(struct zserv *client) { - /* type of protocol (lib/zebra.h) */ - u_char proto; - u_short instance; + /* type of protocol (lib/zebra.h) */ + u_char proto; + u_short instance; - proto = stream_getc (client->ibuf); - instance = stream_getw (client->ibuf); + proto = stream_getc(client->ibuf); + instance = stream_getw(client->ibuf); - /* accept only dynamic routing protocols */ - if ((proto < ZEBRA_ROUTE_MAX) - && (proto > ZEBRA_ROUTE_STATIC)) - { - zlog_notice ("client %d says hello and bids fair to announce only %s routes", - client->sock, zebra_route_string(proto)); - if (instance) - zlog_notice ("client protocol instance %d", instance); + /* accept only dynamic routing protocols */ + if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_STATIC)) { + zlog_notice( + "client %d says hello and bids fair to announce only %s routes", + client->sock, zebra_route_string(proto)); + if (instance) + zlog_notice("client protocol instance %d", instance); - client->proto = proto; - client->instance = instance; - } + client->proto = proto; + client->instance = instance; + } } /* Unregister all information in a VRF. */ -static int -zread_vrf_unregister (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ - int i; - afi_t afi; - - for (afi = AFI_IP; afi < AFI_MAX; afi++) - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - vrf_bitmap_unset (client->redist[afi][i], zvrf_id (zvrf)); - vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf)); - vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf)); - vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf)); - - return 0; -} - -static void -zread_mpls_labels (int command, struct zserv *client, u_short length, - vrf_id_t vrf_id) -{ - struct stream *s; - enum lsp_types_t type; - struct prefix prefix; - enum nexthop_types_t gtype; - union g_addr gate; - ifindex_t ifindex; - mpls_label_t in_label, out_label; - u_int8_t distance; - struct zebra_vrf *zvrf; - - zvrf = vrf_info_lookup (vrf_id); - if (!zvrf) - return; - - /* Get input stream. */ - s = client->ibuf; - - /* Get data. */ - type = stream_getc (s); - prefix.family = stream_getl (s); - switch (prefix.family) - { - case AF_INET: - prefix.u.prefix4.s_addr = stream_get_ipv4 (s); - prefix.prefixlen = stream_getc (s); - gate.ipv4.s_addr = stream_get_ipv4 (s); - break; - case AF_INET6: - stream_get (&prefix.u.prefix6, s, 16); - prefix.prefixlen = stream_getc (s); - stream_get (&gate.ipv6, s, 16); - break; - default: - return; - } - ifindex = stream_getl (s); - distance = stream_getc (s); - in_label = stream_getl (s); - out_label = stream_getl (s); - - switch (prefix.family) - { - case AF_INET: - if (ifindex) - gtype = NEXTHOP_TYPE_IPV4_IFINDEX; - else - gtype = NEXTHOP_TYPE_IPV4; - break; - case AF_INET6: - if (ifindex) - gtype = NEXTHOP_TYPE_IPV6_IFINDEX; - else - gtype = NEXTHOP_TYPE_IPV6; - break; - default: - return; - } - - if (! mpls_enabled) - return; - - if (command == ZEBRA_MPLS_LABELS_ADD) - { - mpls_lsp_install (zvrf, type, in_label, out_label, gtype, &gate, - ifindex); - if (out_label != MPLS_IMP_NULL_LABEL) - mpls_ftn_update (1, zvrf, type, &prefix, gtype, &gate, ifindex, - distance, out_label); - } - else if (command == ZEBRA_MPLS_LABELS_DELETE) - { - mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, ifindex); - if (out_label != MPLS_IMP_NULL_LABEL) - mpls_ftn_update (0, zvrf, type, &prefix, gtype, &gate, ifindex, - distance, out_label); - } +static int zread_vrf_unregister(struct zserv *client, u_short length, + struct zebra_vrf *zvrf) +{ + int i; + afi_t afi; + + for (afi = AFI_IP; afi < AFI_MAX; afi++) + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) + vrf_bitmap_unset(client->redist[afi][i], zvrf_id(zvrf)); + vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf)); + vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf)); + vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf)); + + return 0; +} + +static void zread_mpls_labels(int command, struct zserv *client, u_short length, + vrf_id_t vrf_id) +{ + struct stream *s; + enum lsp_types_t type; + struct prefix prefix; + enum nexthop_types_t gtype; + union g_addr gate; + ifindex_t ifindex; + mpls_label_t in_label, out_label; + u_int8_t distance; + struct zebra_vrf *zvrf; + + zvrf = vrf_info_lookup(vrf_id); + if (!zvrf) + return; + + /* Get input stream. */ + s = client->ibuf; + + /* Get data. */ + type = stream_getc(s); + prefix.family = stream_getl(s); + switch (prefix.family) { + case AF_INET: + prefix.u.prefix4.s_addr = stream_get_ipv4(s); + prefix.prefixlen = stream_getc(s); + gate.ipv4.s_addr = stream_get_ipv4(s); + break; + case AF_INET6: + stream_get(&prefix.u.prefix6, s, 16); + prefix.prefixlen = stream_getc(s); + stream_get(&gate.ipv6, s, 16); + break; + default: + return; + } + ifindex = stream_getl(s); + distance = stream_getc(s); + in_label = stream_getl(s); + out_label = stream_getl(s); + + switch (prefix.family) { + case AF_INET: + if (ifindex) + gtype = NEXTHOP_TYPE_IPV4_IFINDEX; + else + gtype = NEXTHOP_TYPE_IPV4; + break; + case AF_INET6: + if (ifindex) + gtype = NEXTHOP_TYPE_IPV6_IFINDEX; + else + gtype = NEXTHOP_TYPE_IPV6; + break; + default: + return; + } + + if (!mpls_enabled) + return; + + if (command == ZEBRA_MPLS_LABELS_ADD) { + mpls_lsp_install(zvrf, type, in_label, out_label, gtype, &gate, + ifindex); + if (out_label != MPLS_IMP_NULL_LABEL) + mpls_ftn_update(1, zvrf, type, &prefix, gtype, &gate, + ifindex, distance, out_label); + } else if (command == ZEBRA_MPLS_LABELS_DELETE) { + mpls_lsp_uninstall(zvrf, type, in_label, gtype, &gate, ifindex); + if (out_label != MPLS_IMP_NULL_LABEL) + mpls_ftn_update(0, zvrf, type, &prefix, gtype, &gate, + ifindex, distance, out_label); + } } /* Send response to a label manager connect request to client */ -static int -zsend_label_manager_connect_response (struct zserv *client, vrf_id_t vrf_id, u_short result) +static int zsend_label_manager_connect_response(struct zserv *client, + vrf_id_t vrf_id, u_short result) { - struct stream *s; + struct stream *s; - s = client->obuf; - stream_reset (s); + s = client->obuf; + stream_reset(s); - zserv_create_header (s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id); + zserv_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id); - /* result */ - stream_putc (s, result); + /* result */ + stream_putc(s, result); - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); - return writen (client->sock, s->data, stream_get_endp (s)); + return writen(client->sock, s->data, stream_get_endp(s)); } -static void -zread_label_manager_connect (struct zserv *client, vrf_id_t vrf_id) +static void zread_label_manager_connect(struct zserv *client, vrf_id_t vrf_id) { - struct stream *s; - /* type of protocol (lib/zebra.h) */ - u_char proto; - u_short instance; + struct stream *s; + /* type of protocol (lib/zebra.h) */ + u_char proto; + u_short instance; - /* Get input stream. */ - s = client->ibuf; + /* Get input stream. */ + s = client->ibuf; - /* Get data. */ - proto = stream_getc (s); - instance = stream_getw (s); + /* Get data. */ + proto = stream_getc(s); + instance = stream_getw(s); - /* accept only dynamic routing protocols */ - if ((proto >= ZEBRA_ROUTE_MAX) - || (proto <= ZEBRA_ROUTE_STATIC)) - { - zlog_err ("client %d has wrong protocol %s", - client->sock, zebra_route_string(proto)); - zsend_label_manager_connect_response (client, vrf_id, 1); - return; - } - zlog_notice ("client %d with instance %u connected as %s", - client->sock, instance, zebra_route_string(proto)); - client->proto = proto; - client->instance = instance; - - /* - Release previous labels of same protocol and instance. - This is done in case it restarted from an unexpected shutdown. - */ - release_daemon_chunks (proto, instance); - - zlog_debug (" Label Manager client connected: sock %d, proto %s, instance %u", - client->sock, zebra_route_string(proto), instance); - /* send response back */ - zsend_label_manager_connect_response (client, vrf_id, 0); + /* accept only dynamic routing protocols */ + if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) { + zlog_err("client %d has wrong protocol %s", client->sock, + zebra_route_string(proto)); + zsend_label_manager_connect_response(client, vrf_id, 1); + return; + } + zlog_notice("client %d with instance %u connected as %s", client->sock, + instance, zebra_route_string(proto)); + client->proto = proto; + client->instance = instance; + + /* + Release previous labels of same protocol and instance. + This is done in case it restarted from an unexpected shutdown. + */ + release_daemon_chunks(proto, instance); + + zlog_debug( + " Label Manager client connected: sock %d, proto %s, instance %u", + client->sock, zebra_route_string(proto), instance); + /* send response back */ + zsend_label_manager_connect_response(client, vrf_id, 0); } /* Send response to a get label chunk request to client */ -static int -zsend_assign_label_chunk_response (struct zserv *client, vrf_id_t vrf_id, - struct label_manager_chunk *lmc) +static int zsend_assign_label_chunk_response(struct zserv *client, + vrf_id_t vrf_id, + struct label_manager_chunk *lmc) { - struct stream *s; - - s = client->obuf; - stream_reset (s); + struct stream *s; - zserv_create_header (s, ZEBRA_GET_LABEL_CHUNK, vrf_id); + s = client->obuf; + stream_reset(s); - if (lmc) - { - /* keep */ - stream_putc (s, lmc->keep); - /* start and end labels */ - stream_putl (s, lmc->start); - stream_putl (s, lmc->end); + zserv_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id); - } + if (lmc) { + /* keep */ + stream_putc(s, lmc->keep); + /* start and end labels */ + stream_putl(s, lmc->start); + stream_putl(s, lmc->end); + } - /* Write packet size. */ - stream_putw_at (s, 0, stream_get_endp (s)); + /* Write packet size. */ + stream_putw_at(s, 0, stream_get_endp(s)); - return writen (client->sock, s->data, stream_get_endp (s)); + return writen(client->sock, s->data, stream_get_endp(s)); } -static void -zread_get_label_chunk (struct zserv *client, vrf_id_t vrf_id) +static void zread_get_label_chunk(struct zserv *client, vrf_id_t vrf_id) { - struct stream *s; - u_char keep; - uint32_t size; - struct label_manager_chunk *lmc; + struct stream *s; + u_char keep; + uint32_t size; + struct label_manager_chunk *lmc; - /* Get input stream. */ - s = client->ibuf; + /* Get input stream. */ + s = client->ibuf; - /* Get data. */ - keep = stream_getc (s); - size = stream_getl (s); + /* Get data. */ + keep = stream_getc(s); + size = stream_getl(s); - lmc = assign_label_chunk (client->proto, client->instance, keep, size); - if (!lmc) - zlog_err ("%s: Unable to assign Label Chunk of size %u", __func__, size); - else - zlog_debug ("Assigned Label Chunk %u - %u to %u", - lmc->start, lmc->end, keep); - /* send response back */ - zsend_assign_label_chunk_response (client, vrf_id, lmc); + lmc = assign_label_chunk(client->proto, client->instance, keep, size); + if (!lmc) + zlog_err("%s: Unable to assign Label Chunk of size %u", + __func__, size); + else + zlog_debug("Assigned Label Chunk %u - %u to %u", lmc->start, + lmc->end, keep); + /* send response back */ + zsend_assign_label_chunk_response(client, vrf_id, lmc); +} + +static void zread_release_label_chunk(struct zserv *client) +{ + struct stream *s; + uint32_t start, end; + + /* Get input stream. */ + s = client->ibuf; + + /* Get data. */ + start = stream_getl(s); + end = stream_getl(s); + + release_label_chunk(client->proto, client->instance, start, end); +} +static void zread_label_manager_request(int cmd, struct zserv *client, + vrf_id_t vrf_id) +{ + /* to avoid sending other messages like ZERBA_INTERFACE_UP */ + if (cmd == ZEBRA_LABEL_MANAGER_CONNECT) + client->is_synchronous = 1; + + /* external label manager */ + if (lm_is_external) + zread_relay_label_manager_request(cmd, client, vrf_id); + /* this is a label manager */ + else { + if (cmd == ZEBRA_LABEL_MANAGER_CONNECT) + zread_label_manager_connect(client, vrf_id); + else { + /* Sanity: don't allow 'unidentified' requests */ + if (!client->proto) { + zlog_err( + "Got label request from an unidentified client"); + return; + } + if (cmd == ZEBRA_GET_LABEL_CHUNK) + zread_get_label_chunk(client, vrf_id); + else if (cmd == ZEBRA_RELEASE_LABEL_CHUNK) + zread_release_label_chunk(client); + } + } } -static void -zread_release_label_chunk (struct zserv *client) +/* Cleanup registered nexthops (across VRFs) upon client disconnect. */ +static void zebra_client_close_cleanup_rnh(struct zserv *client) { - struct stream *s; - uint32_t start, end; - - /* Get input stream. */ - s = client->ibuf; + struct vrf *vrf; + struct zebra_vrf *zvrf; - /* Get data. */ - start = stream_getl (s); - end = stream_getl (s); - - release_label_chunk (client->proto, client->instance, start, end); + RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) + { + if ((zvrf = vrf->info) != NULL) { + zebra_cleanup_rnh_client(zvrf_id(zvrf), AF_INET, client, + RNH_NEXTHOP_TYPE); + zebra_cleanup_rnh_client(zvrf_id(zvrf), AF_INET6, + client, RNH_NEXTHOP_TYPE); + zebra_cleanup_rnh_client(zvrf_id(zvrf), AF_INET, client, + RNH_IMPORT_CHECK_TYPE); + zebra_cleanup_rnh_client(zvrf_id(zvrf), AF_INET6, + client, RNH_IMPORT_CHECK_TYPE); + if (client->proto == ZEBRA_ROUTE_LDP) { + hash_iterate(zvrf->lsp_table, + mpls_ldp_lsp_uninstall_all, + zvrf->lsp_table); + mpls_ldp_ftn_uninstall_all(zvrf, AFI_IP); + mpls_ldp_ftn_uninstall_all(zvrf, AFI_IP6); + } + } + } } -static void -zread_label_manager_request (int cmd, struct zserv *client, vrf_id_t vrf_id) + +/* Close zebra client. */ +static void zebra_client_close(struct zserv *client) { - /* to avoid sending other messages like ZERBA_INTERFACE_UP */ - if (cmd == ZEBRA_LABEL_MANAGER_CONNECT) - client->is_synchronous = 1; + /* Send client de-registration to BFD */ + zebra_ptm_bfd_client_deregister(client->proto); - /* external label manager */ - if (lm_is_external) - zread_relay_label_manager_request (cmd, client, vrf_id); - /* this is a label manager */ - else - { - if (cmd == ZEBRA_LABEL_MANAGER_CONNECT) - zread_label_manager_connect (client, vrf_id); - else - { - /* Sanity: don't allow 'unidentified' requests */ - if (!client->proto) - { - zlog_err ("Got label request from an unidentified client"); - return; - } - if (cmd == ZEBRA_GET_LABEL_CHUNK) - zread_get_label_chunk (client, vrf_id); - else if (cmd == ZEBRA_RELEASE_LABEL_CHUNK) - zread_release_label_chunk (client); - } - } -} + /* Cleanup any registered nexthops - across all VRFs. */ + zebra_client_close_cleanup_rnh(client); -/* Cleanup registered nexthops (across VRFs) upon client disconnect. */ -static void -zebra_client_close_cleanup_rnh (struct zserv *client) -{ - struct vrf *vrf; - struct zebra_vrf *zvrf; - - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) - { - if ((zvrf = vrf->info) != NULL) - { - zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_NEXTHOP_TYPE); - zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_NEXTHOP_TYPE); - zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_IMPORT_CHECK_TYPE); - zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_IMPORT_CHECK_TYPE); - if (client->proto == ZEBRA_ROUTE_LDP) - { - hash_iterate(zvrf->lsp_table, mpls_ldp_lsp_uninstall_all, - zvrf->lsp_table); - mpls_ldp_ftn_uninstall_all (zvrf, AFI_IP); - mpls_ldp_ftn_uninstall_all (zvrf, AFI_IP6); - } - } - } -} + /* Release Label Manager chunks */ + release_daemon_chunks(client->proto, client->instance); -/* Close zebra client. */ -static void -zebra_client_close (struct zserv *client) -{ - /* Send client de-registration to BFD */ - zebra_ptm_bfd_client_deregister(client->proto); - - /* Cleanup any registered nexthops - across all VRFs. */ - zebra_client_close_cleanup_rnh (client); - - /* Release Label Manager chunks */ - release_daemon_chunks (client->proto, client->instance); - - /* Cleanup any FECs registered by this client. */ - zebra_mpls_cleanup_fecs_for_client (vrf_info_lookup(VRF_DEFAULT), client); - - /* Close file descriptor. */ - if (client->sock) - { - unsigned long nroutes; - - close (client->sock); - nroutes = rib_score_proto (client->proto, client->instance); - zlog_notice ("client %d disconnected. %lu %s routes removed from the rib", - client->sock, nroutes, zebra_route_string (client->proto)); - client->sock = -1; - } - - /* Free stream buffers. */ - if (client->ibuf) - stream_free (client->ibuf); - if (client->obuf) - stream_free (client->obuf); - if (client->wb) - buffer_free(client->wb); - - /* Release threads. */ - if (client->t_read) - thread_cancel (client->t_read); - if (client->t_write) - thread_cancel (client->t_write); - if (client->t_suicide) - thread_cancel (client->t_suicide); - - /* Free bitmaps. */ - for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) - for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) - vrf_bitmap_free (client->redist[afi][i]); - - vrf_bitmap_free (client->redist_default); - vrf_bitmap_free (client->ifinfo); - vrf_bitmap_free (client->ridinfo); - - /* Free client structure. */ - listnode_delete (zebrad.client_list, client); - XFREE (MTYPE_TMP, client); + /* Cleanup any FECs registered by this client. */ + zebra_mpls_cleanup_fecs_for_client(vrf_info_lookup(VRF_DEFAULT), + client); + + /* Close file descriptor. */ + if (client->sock) { + unsigned long nroutes; + + close(client->sock); + nroutes = rib_score_proto(client->proto, client->instance); + zlog_notice( + "client %d disconnected. %lu %s routes removed from the rib", + client->sock, nroutes, + zebra_route_string(client->proto)); + client->sock = -1; + } + + /* Free stream buffers. */ + if (client->ibuf) + stream_free(client->ibuf); + if (client->obuf) + stream_free(client->obuf); + if (client->wb) + buffer_free(client->wb); + + /* Release threads. */ + if (client->t_read) + thread_cancel(client->t_read); + if (client->t_write) + thread_cancel(client->t_write); + if (client->t_suicide) + thread_cancel(client->t_suicide); + + /* Free bitmaps. */ + for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) + for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) + vrf_bitmap_free(client->redist[afi][i]); + + vrf_bitmap_free(client->redist_default); + vrf_bitmap_free(client->ifinfo); + vrf_bitmap_free(client->ridinfo); + + /* Free client structure. */ + listnode_delete(zebrad.client_list, client); + XFREE(MTYPE_TMP, client); } /* Make new client. */ -static void -zebra_client_create (int sock) +static void zebra_client_create(int sock) { - struct zserv *client; - int i; - afi_t afi; + struct zserv *client; + int i; + afi_t afi; + + client = XCALLOC(MTYPE_TMP, sizeof(struct zserv)); - client = XCALLOC (MTYPE_TMP, sizeof (struct zserv)); + /* Make client input/output buffer. */ + client->sock = sock; + client->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ); + client->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ); + client->wb = buffer_new(0); - /* Make client input/output buffer. */ - client->sock = sock; - client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ); - client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ); - client->wb = buffer_new(0); + /* Set table number. */ + client->rtm_table = zebrad.rtm_table_default; - /* Set table number. */ - client->rtm_table = zebrad.rtm_table_default; + client->connect_time = monotime(NULL); + /* Initialize flags */ + for (afi = AFI_IP; afi < AFI_MAX; afi++) + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) + client->redist[afi][i] = vrf_bitmap_init(); + client->redist_default = vrf_bitmap_init(); + client->ifinfo = vrf_bitmap_init(); + client->ridinfo = vrf_bitmap_init(); - client->connect_time = monotime(NULL); - /* Initialize flags */ - for (afi = AFI_IP; afi < AFI_MAX; afi++) - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - client->redist[afi][i] = vrf_bitmap_init (); - client->redist_default = vrf_bitmap_init (); - client->ifinfo = vrf_bitmap_init (); - client->ridinfo = vrf_bitmap_init (); + /* by default, it's not a synchronous client */ + client->is_synchronous = 0; - /* by default, it's not a synchronous client */ - client->is_synchronous = 0; + /* Add this client to linked list. */ + listnode_add(zebrad.client_list, client); - /* Add this client to linked list. */ - listnode_add (zebrad.client_list, client); - - /* Make new read thread. */ - zebra_event (ZEBRA_READ, sock, client); + /* Make new read thread. */ + zebra_event(ZEBRA_READ, sock, client); - zebra_vrf_update_all (client); + zebra_vrf_update_all(client); } /* Handler of zebra service request. */ -static int -zebra_client_read (struct thread *thread) -{ - int sock; - struct zserv *client; - size_t already; - uint16_t length, command; - uint8_t marker, version; - vrf_id_t vrf_id; - struct zebra_vrf *zvrf; - - /* Get thread data. Reset reading thread because I'm running. */ - sock = THREAD_FD (thread); - client = THREAD_ARG (thread); - client->t_read = NULL; - - if (client->t_suicide) - { - zebra_client_close(client); - return -1; - } - - /* Read length and command (if we don't have it already). */ - if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE) - { - ssize_t nbyte; - if (((nbyte = stream_read_try (client->ibuf, sock, - ZEBRA_HEADER_SIZE-already)) == 0) || - (nbyte == -1)) - { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("connection closed socket [%d]", sock); - zebra_client_close (client); - return -1; +static int zebra_client_read(struct thread *thread) +{ + int sock; + struct zserv *client; + size_t already; + uint16_t length, command; + uint8_t marker, version; + vrf_id_t vrf_id; + struct zebra_vrf *zvrf; + + /* Get thread data. Reset reading thread because I'm running. */ + sock = THREAD_FD(thread); + client = THREAD_ARG(thread); + client->t_read = NULL; + + if (client->t_suicide) { + zebra_client_close(client); + return -1; } - if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already)) - { - /* Try again later. */ - zebra_event (ZEBRA_READ, sock, client); - return 0; + + /* Read length and command (if we don't have it already). */ + if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE) { + ssize_t nbyte; + if (((nbyte = stream_read_try(client->ibuf, sock, + ZEBRA_HEADER_SIZE - already)) + == 0) + || (nbyte == -1)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("connection closed socket [%d]", + sock); + zebra_client_close(client); + return -1; + } + if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) { + /* Try again later. */ + zebra_event(ZEBRA_READ, sock, client); + return 0; + } + already = ZEBRA_HEADER_SIZE; } - already = ZEBRA_HEADER_SIZE; - } - - /* Reset to read from the beginning of the incoming packet. */ - stream_set_getp(client->ibuf, 0); - - /* Fetch header values */ - length = stream_getw (client->ibuf); - marker = stream_getc (client->ibuf); - version = stream_getc (client->ibuf); - vrf_id = stream_getw (client->ibuf); - command = stream_getw (client->ibuf); - - if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) - { - zlog_err("%s: socket %d version mismatch, marker %d, version %d", - __func__, sock, marker, version); - zebra_client_close (client); - return -1; - } - if (length < ZEBRA_HEADER_SIZE) - { - zlog_warn("%s: socket %d message length %u is less than header size %d", - __func__, sock, length, ZEBRA_HEADER_SIZE); - zebra_client_close (client); - return -1; - } - if (length > STREAM_SIZE(client->ibuf)) - { - zlog_warn("%s: socket %d message length %u exceeds buffer size %lu", - __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf)); - zebra_client_close (client); - return -1; - } - - /* Read rest of data. */ - if (already < length) - { - ssize_t nbyte; - if (((nbyte = stream_read_try (client->ibuf, sock, - length-already)) == 0) || - (nbyte == -1)) - { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("connection closed [%d] when reading zebra data", sock); - zebra_client_close (client); - return -1; + + /* Reset to read from the beginning of the incoming packet. */ + stream_set_getp(client->ibuf, 0); + + /* Fetch header values */ + length = stream_getw(client->ibuf); + marker = stream_getc(client->ibuf); + version = stream_getc(client->ibuf); + vrf_id = stream_getw(client->ibuf); + command = stream_getw(client->ibuf); + + if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { + zlog_err( + "%s: socket %d version mismatch, marker %d, version %d", + __func__, sock, marker, version); + zebra_client_close(client); + return -1; + } + if (length < ZEBRA_HEADER_SIZE) { + zlog_warn( + "%s: socket %d message length %u is less than header size %d", + __func__, sock, length, ZEBRA_HEADER_SIZE); + zebra_client_close(client); + return -1; + } + if (length > STREAM_SIZE(client->ibuf)) { + zlog_warn( + "%s: socket %d message length %u exceeds buffer size %lu", + __func__, sock, length, + (u_long)STREAM_SIZE(client->ibuf)); + zebra_client_close(client); + return -1; } - if (nbyte != (ssize_t)(length-already)) - { - /* Try again later. */ - zebra_event (ZEBRA_READ, sock, client); - return 0; + + /* Read rest of data. */ + if (already < length) { + ssize_t nbyte; + if (((nbyte = stream_read_try(client->ibuf, sock, + length - already)) + == 0) + || (nbyte == -1)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug( + "connection closed [%d] when reading zebra data", + sock); + zebra_client_close(client); + return -1; + } + if (nbyte != (ssize_t)(length - already)) { + /* Try again later. */ + zebra_event(ZEBRA_READ, sock, client); + return 0; + } + } + + length -= ZEBRA_HEADER_SIZE; + + /* Debug packet information. */ + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("zebra message comes from socket [%d]", sock); + + if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) + zlog_debug("zebra message received [%s] %d in VRF %u", + zserv_command_string(command), length, vrf_id); + + client->last_read_time = monotime(NULL); + client->last_read_cmd = command; + + zvrf = zebra_vrf_lookup_by_id(vrf_id); + if (!zvrf) { + if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) + zlog_debug("zebra received unknown VRF[%u]", vrf_id); + goto zclient_read_out; } - } - - length -= ZEBRA_HEADER_SIZE; - - /* Debug packet information. */ - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("zebra message comes from socket [%d]", sock); - - if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) - zlog_debug ("zebra message received [%s] %d in VRF %u", - zserv_command_string (command), length, vrf_id); - - client->last_read_time = monotime(NULL); - client->last_read_cmd = command; - - zvrf = zebra_vrf_lookup_by_id (vrf_id); - if (!zvrf) - { - if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) - zlog_debug ("zebra received unknown VRF[%u]", vrf_id); - goto zclient_read_out; - } - - switch (command) - { - case ZEBRA_ROUTER_ID_ADD: - zread_router_id_add (client, length, zvrf); - break; - case ZEBRA_ROUTER_ID_DELETE: - zread_router_id_delete (client, length, zvrf); - break; - case ZEBRA_INTERFACE_ADD: - zread_interface_add (client, length, zvrf); - break; - case ZEBRA_INTERFACE_DELETE: - zread_interface_delete (client, length, zvrf); - break; - case ZEBRA_IPV4_ROUTE_ADD: - zread_ipv4_add (client, length, zvrf); - break; - case ZEBRA_IPV4_ROUTE_DELETE: - zread_ipv4_delete (client, length, zvrf); - break; - case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD: - zread_ipv4_route_ipv6_nexthop_add (client, length, zvrf); - break; - case ZEBRA_IPV4_NEXTHOP_ADD: - zread_ipv4_add(client, length, zvrf); /* LB: r1.0 merge - id was 1 */ - break; - case ZEBRA_IPV4_NEXTHOP_DELETE: - zread_ipv4_delete(client, length, zvrf); /* LB: r1.0 merge - id was 1 */ - break; - case ZEBRA_IPV6_ROUTE_ADD: - zread_ipv6_add (client, length, zvrf); - break; - case ZEBRA_IPV6_ROUTE_DELETE: - zread_ipv6_delete (client, length, zvrf); - break; - case ZEBRA_REDISTRIBUTE_ADD: - zebra_redistribute_add (command, client, length, zvrf); - break; - case ZEBRA_REDISTRIBUTE_DELETE: - zebra_redistribute_delete (command, client, length, zvrf); - break; - case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: - zebra_redistribute_default_add (command, client, length, zvrf); - break; - case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: - zebra_redistribute_default_delete (command, client, length, zvrf); - break; - case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB: - zread_ipv4_nexthop_lookup_mrib (client, length, zvrf); - break; - case ZEBRA_HELLO: - zread_hello (client); - break; - case ZEBRA_NEXTHOP_REGISTER: - zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE, zvrf); - break; - case ZEBRA_NEXTHOP_UNREGISTER: - zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE, zvrf); - break; - case ZEBRA_IMPORT_ROUTE_REGISTER: - zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE, zvrf); - break; - case ZEBRA_IMPORT_ROUTE_UNREGISTER: - zserv_rnh_unregister(client, sock, length, RNH_IMPORT_CHECK_TYPE, zvrf); - break; - case ZEBRA_BFD_DEST_UPDATE: - case ZEBRA_BFD_DEST_REGISTER: - zebra_ptm_bfd_dst_register(client, sock, length, command, zvrf); - break; - case ZEBRA_BFD_DEST_DEREGISTER: - zebra_ptm_bfd_dst_deregister(client, sock, length, zvrf); - break; - case ZEBRA_VRF_UNREGISTER: - zread_vrf_unregister (client, length, zvrf); - break; - case ZEBRA_BFD_CLIENT_REGISTER: - zebra_ptm_bfd_client_register(client, sock, length); - break; - case ZEBRA_INTERFACE_ENABLE_RADV: -#if defined (HAVE_RTADV) - zebra_interface_radv_set (client, sock, length, zvrf, 1); + + switch (command) { + case ZEBRA_ROUTER_ID_ADD: + zread_router_id_add(client, length, zvrf); + break; + case ZEBRA_ROUTER_ID_DELETE: + zread_router_id_delete(client, length, zvrf); + break; + case ZEBRA_INTERFACE_ADD: + zread_interface_add(client, length, zvrf); + break; + case ZEBRA_INTERFACE_DELETE: + zread_interface_delete(client, length, zvrf); + break; + case ZEBRA_IPV4_ROUTE_ADD: + zread_ipv4_add(client, length, zvrf); + break; + case ZEBRA_IPV4_ROUTE_DELETE: + zread_ipv4_delete(client, length, zvrf); + break; + case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD: + zread_ipv4_route_ipv6_nexthop_add(client, length, zvrf); + break; + case ZEBRA_IPV4_NEXTHOP_ADD: + zread_ipv4_add(client, length, + zvrf); /* LB: r1.0 merge - id was 1 */ + break; + case ZEBRA_IPV4_NEXTHOP_DELETE: + zread_ipv4_delete(client, length, + zvrf); /* LB: r1.0 merge - id was 1 */ + break; + case ZEBRA_IPV6_ROUTE_ADD: + zread_ipv6_add(client, length, zvrf); + break; + case ZEBRA_IPV6_ROUTE_DELETE: + zread_ipv6_delete(client, length, zvrf); + break; + case ZEBRA_REDISTRIBUTE_ADD: + zebra_redistribute_add(command, client, length, zvrf); + break; + case ZEBRA_REDISTRIBUTE_DELETE: + zebra_redistribute_delete(command, client, length, zvrf); + break; + case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: + zebra_redistribute_default_add(command, client, length, zvrf); + break; + case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: + zebra_redistribute_default_delete(command, client, length, + zvrf); + break; + case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB: + zread_ipv4_nexthop_lookup_mrib(client, length, zvrf); + break; + case ZEBRA_HELLO: + zread_hello(client); + break; + case ZEBRA_NEXTHOP_REGISTER: + zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE, + zvrf); + break; + case ZEBRA_NEXTHOP_UNREGISTER: + zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE, + zvrf); + break; + case ZEBRA_IMPORT_ROUTE_REGISTER: + zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE, + zvrf); + break; + case ZEBRA_IMPORT_ROUTE_UNREGISTER: + zserv_rnh_unregister(client, sock, length, + RNH_IMPORT_CHECK_TYPE, zvrf); + break; + case ZEBRA_BFD_DEST_UPDATE: + case ZEBRA_BFD_DEST_REGISTER: + zebra_ptm_bfd_dst_register(client, sock, length, command, zvrf); + break; + case ZEBRA_BFD_DEST_DEREGISTER: + zebra_ptm_bfd_dst_deregister(client, sock, length, zvrf); + break; + case ZEBRA_VRF_UNREGISTER: + zread_vrf_unregister(client, length, zvrf); + break; + case ZEBRA_BFD_CLIENT_REGISTER: + zebra_ptm_bfd_client_register(client, sock, length); + break; + case ZEBRA_INTERFACE_ENABLE_RADV: +#if defined(HAVE_RTADV) + zebra_interface_radv_set(client, sock, length, zvrf, 1); #endif - break; - case ZEBRA_INTERFACE_DISABLE_RADV: -#if defined (HAVE_RTADV) - zebra_interface_radv_set (client, sock, length, zvrf, 0); + break; + case ZEBRA_INTERFACE_DISABLE_RADV: +#if defined(HAVE_RTADV) + zebra_interface_radv_set(client, sock, length, zvrf, 0); #endif - break; - case ZEBRA_MPLS_LABELS_ADD: - case ZEBRA_MPLS_LABELS_DELETE: - zread_mpls_labels (command, client, length, vrf_id); - break; - case ZEBRA_IPMR_ROUTE_STATS: - zebra_ipmr_route_stats (client, sock, length, zvrf); - break; - case ZEBRA_LABEL_MANAGER_CONNECT: - case ZEBRA_GET_LABEL_CHUNK: - case ZEBRA_RELEASE_LABEL_CHUNK: - zread_label_manager_request (command, client, vrf_id); - break; - case ZEBRA_FEC_REGISTER: - zserv_fec_register (client, sock, length); - break; - case ZEBRA_FEC_UNREGISTER: - zserv_fec_unregister (client, sock, length); - break; - case ZEBRA_ADVERTISE_ALL_VNI: - zebra_vxlan_advertise_all_vni (client, sock, length, zvrf); - break; - case ZEBRA_REMOTE_VTEP_ADD: - zebra_vxlan_remote_vtep_add (client, sock, length, zvrf); - break; - case ZEBRA_REMOTE_VTEP_DEL: - zebra_vxlan_remote_vtep_del (client, sock, length, zvrf); - break; - case ZEBRA_REMOTE_MACIP_ADD: - zebra_vxlan_remote_macip_add (client, sock, length, zvrf); - break; - case ZEBRA_REMOTE_MACIP_DEL: - zebra_vxlan_remote_macip_del (client, sock, length, zvrf); - break; - default: - zlog_info ("Zebra received unknown command %d", command); - break; - } - - if (client->t_suicide) - { - /* No need to wait for thread callback, just kill immediately. */ - zebra_client_close(client); - return -1; - } - - zclient_read_out: - stream_reset (client->ibuf); - zebra_event (ZEBRA_READ, sock, client); - return 0; + break; + case ZEBRA_MPLS_LABELS_ADD: + case ZEBRA_MPLS_LABELS_DELETE: + zread_mpls_labels(command, client, length, vrf_id); + break; + case ZEBRA_IPMR_ROUTE_STATS: + zebra_ipmr_route_stats(client, sock, length, zvrf); + break; + case ZEBRA_LABEL_MANAGER_CONNECT: + case ZEBRA_GET_LABEL_CHUNK: + case ZEBRA_RELEASE_LABEL_CHUNK: + zread_label_manager_request(command, client, vrf_id); + break; + case ZEBRA_FEC_REGISTER: + zserv_fec_register(client, sock, length); + break; + case ZEBRA_FEC_UNREGISTER: + zserv_fec_unregister(client, sock, length); + break; + case ZEBRA_ADVERTISE_ALL_VNI: + zebra_vxlan_advertise_all_vni(client, sock, length, zvrf); + break; + case ZEBRA_REMOTE_VTEP_ADD: + zebra_vxlan_remote_vtep_add(client, sock, length, zvrf); + break; + case ZEBRA_REMOTE_VTEP_DEL: + zebra_vxlan_remote_vtep_del(client, sock, length, zvrf); + break; + case ZEBRA_REMOTE_MACIP_ADD: + zebra_vxlan_remote_macip_add(client, sock, length, zvrf); + break; + case ZEBRA_REMOTE_MACIP_DEL: + zebra_vxlan_remote_macip_del(client, sock, length, zvrf); + break; + default: + zlog_info("Zebra received unknown command %d", command); + break; + } + + if (client->t_suicide) { + /* No need to wait for thread callback, just kill immediately. + */ + zebra_client_close(client); + return -1; + } + +zclient_read_out: + stream_reset(client->ibuf); + zebra_event(ZEBRA_READ, sock, client); + return 0; } /* Accept code of zebra server socket. */ -static int -zebra_accept (struct thread *thread) +static int zebra_accept(struct thread *thread) { - int accept_sock; - int client_sock; - struct sockaddr_in client; - socklen_t len; + int accept_sock; + int client_sock; + struct sockaddr_in client; + socklen_t len; + + accept_sock = THREAD_FD(thread); - accept_sock = THREAD_FD (thread); + /* Reregister myself. */ + zebra_event(ZEBRA_SERV, accept_sock, NULL); - /* Reregister myself. */ - zebra_event (ZEBRA_SERV, accept_sock, NULL); + len = sizeof(struct sockaddr_in); + client_sock = accept(accept_sock, (struct sockaddr *)&client, &len); - len = sizeof (struct sockaddr_in); - client_sock = accept (accept_sock, (struct sockaddr *) &client, &len); + if (client_sock < 0) { + zlog_warn("Can't accept zebra socket: %s", + safe_strerror(errno)); + return -1; + } - if (client_sock < 0) - { - zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno)); - return -1; - } + /* Make client socket non-blocking. */ + set_nonblocking(client_sock); - /* Make client socket non-blocking. */ - set_nonblocking(client_sock); - - /* Create new zebra client. */ - zebra_client_create (client_sock); + /* Create new zebra client. */ + zebra_client_create(client_sock); - return 0; + return 0; } #ifdef HAVE_TCP_ZEBRA /* Make zebra's server socket. */ -static void -zebra_serv () -{ - int ret; - int accept_sock; - struct sockaddr_in addr; - - accept_sock = socket (AF_INET, SOCK_STREAM, 0); - - if (accept_sock < 0) - { - zlog_warn ("Can't create zserv stream socket: %s", - safe_strerror (errno)); - zlog_warn ("zebra can't provice full functionality due to above error"); - return; - } - - memset (&addr, 0, sizeof (struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons (ZEBRA_PORT); +static void zebra_serv() +{ + int ret; + int accept_sock; + struct sockaddr_in addr; + + accept_sock = socket(AF_INET, SOCK_STREAM, 0); + + if (accept_sock < 0) { + zlog_warn("Can't create zserv stream socket: %s", + safe_strerror(errno)); + zlog_warn( + "zebra can't provice full functionality due to above error"); + return; + } + + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(ZEBRA_PORT); #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - addr.sin_len = sizeof (struct sockaddr_in); + addr.sin_len = sizeof(struct sockaddr_in); #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - - sockopt_reuseaddr (accept_sock); - sockopt_reuseport (accept_sock); - - if ( zserv_privs.change(ZPRIVS_RAISE) ) - zlog_err("Can't raise privileges"); - - ret = bind (accept_sock, (struct sockaddr *)&addr, - sizeof (struct sockaddr_in)); - if (ret < 0) - { - zlog_warn ("Can't bind to stream socket: %s", - safe_strerror (errno)); - zlog_warn ("zebra can't provice full functionality due to above error"); - close (accept_sock); /* Avoid sd leak. */ - return; - } - - if ( zserv_privs.change(ZPRIVS_LOWER) ) - zlog_err("Can't lower privileges"); - - ret = listen (accept_sock, 1); - if (ret < 0) - { - zlog_warn ("Can't listen to stream socket: %s", - safe_strerror (errno)); - zlog_warn ("zebra can't provice full functionality due to above error"); - close (accept_sock); /* Avoid sd leak. */ - return; - } - - zebra_event (ZEBRA_SERV, accept_sock, NULL); + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + sockopt_reuseaddr(accept_sock); + sockopt_reuseport(accept_sock); + + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog_err("Can't raise privileges"); + + ret = bind(accept_sock, (struct sockaddr *)&addr, + sizeof(struct sockaddr_in)); + if (ret < 0) { + zlog_warn("Can't bind to stream socket: %s", + safe_strerror(errno)); + zlog_warn( + "zebra can't provice full functionality due to above error"); + close(accept_sock); /* Avoid sd leak. */ + return; + } + + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog_err("Can't lower privileges"); + + ret = listen(accept_sock, 1); + if (ret < 0) { + zlog_warn("Can't listen to stream socket: %s", + safe_strerror(errno)); + zlog_warn( + "zebra can't provice full functionality due to above error"); + close(accept_sock); /* Avoid sd leak. */ + return; + } + + zebra_event(ZEBRA_SERV, accept_sock, NULL); } #else /* HAVE_TCP_ZEBRA */ @@ -2566,221 +2521,212 @@ zebra_serv () #include <sys/un.h> /* zebra server UNIX domain socket. */ -static void -zebra_serv_un (const char *path) -{ - int ret; - int sock, len; - struct sockaddr_un serv; - mode_t old_mask; - - /* First of all, unlink existing socket */ - unlink (path); - - /* Set umask */ - old_mask = umask (0077); - - /* Make UNIX domain socket. */ - sock = socket (AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - { - zlog_warn ("Can't create zserv unix socket: %s", - safe_strerror (errno)); - zlog_warn ("zebra can't provide full functionality due to above error"); - return; - } - - /* Make server socket. */ - memset (&serv, 0, sizeof (struct sockaddr_un)); - serv.sun_family = AF_UNIX; - strncpy (serv.sun_path, path, strlen (path)); +static void zebra_serv_un(const char *path) +{ + int ret; + int sock, len; + struct sockaddr_un serv; + mode_t old_mask; + + /* First of all, unlink existing socket */ + unlink(path); + + /* Set umask */ + old_mask = umask(0077); + + /* Make UNIX domain socket. */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + zlog_warn("Can't create zserv unix socket: %s", + safe_strerror(errno)); + zlog_warn( + "zebra can't provide full functionality due to above error"); + return; + } + + /* Make server socket. */ + memset(&serv, 0, sizeof(struct sockaddr_un)); + serv.sun_family = AF_UNIX; + strncpy(serv.sun_path, path, strlen(path)); #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN - len = serv.sun_len = SUN_LEN(&serv); + len = serv.sun_len = SUN_LEN(&serv); #else - len = sizeof (serv.sun_family) + strlen (serv.sun_path); + len = sizeof(serv.sun_family) + strlen(serv.sun_path); #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */ - ret = bind (sock, (struct sockaddr *) &serv, len); - if (ret < 0) - { - zlog_warn ("Can't bind to unix socket %s: %s", - path, safe_strerror (errno)); - zlog_warn ("zebra can't provide full functionality due to above error"); - close (sock); - return; - } - - ret = listen (sock, 5); - if (ret < 0) - { - zlog_warn ("Can't listen to unix socket %s: %s", - path, safe_strerror (errno)); - zlog_warn ("zebra can't provide full functionality due to above error"); - close (sock); - return; - } - - umask (old_mask); - - zebra_event (ZEBRA_SERV, sock, NULL); + ret = bind(sock, (struct sockaddr *)&serv, len); + if (ret < 0) { + zlog_warn("Can't bind to unix socket %s: %s", path, + safe_strerror(errno)); + zlog_warn( + "zebra can't provide full functionality due to above error"); + close(sock); + return; + } + + ret = listen(sock, 5); + if (ret < 0) { + zlog_warn("Can't listen to unix socket %s: %s", path, + safe_strerror(errno)); + zlog_warn( + "zebra can't provide full functionality due to above error"); + close(sock); + return; + } + + umask(old_mask); + + zebra_event(ZEBRA_SERV, sock, NULL); } #endif /* HAVE_TCP_ZEBRA */ -static void -zebra_event (enum event event, int sock, struct zserv *client) -{ - switch (event) - { - case ZEBRA_SERV: - thread_add_read(zebrad.master, zebra_accept, client, sock, NULL); - break; - case ZEBRA_READ: - client->t_read = NULL; - thread_add_read(zebrad.master, zebra_client_read, client, sock, - &client->t_read); - break; - case ZEBRA_WRITE: - /**/ - break; - } +static void zebra_event(enum event event, int sock, struct zserv *client) +{ + switch (event) { + case ZEBRA_SERV: + thread_add_read(zebrad.master, zebra_accept, client, sock, + NULL); + break; + case ZEBRA_READ: + client->t_read = NULL; + thread_add_read(zebrad.master, zebra_client_read, client, sock, + &client->t_read); + break; + case ZEBRA_WRITE: + /**/ + break; + } } #define ZEBRA_TIME_BUF 32 -static char * -zserv_time_buf(time_t *time1, char *buf, int buflen) +static char *zserv_time_buf(time_t *time1, char *buf, int buflen) { - struct tm *tm; - time_t now; + struct tm *tm; + time_t now; - assert (buf != NULL); - assert (buflen >= ZEBRA_TIME_BUF); - assert (time1 != NULL); + assert(buf != NULL); + assert(buflen >= ZEBRA_TIME_BUF); + assert(time1 != NULL); - if (!*time1) - { - snprintf(buf, buflen, "never "); - return (buf); - } + if (!*time1) { + snprintf(buf, buflen, "never "); + return (buf); + } - now = monotime(NULL); - now -= *time1; - tm = gmtime(&now); + now = monotime(NULL); + now -= *time1; + tm = gmtime(&now); - /* Making formatted timer strings. */ +/* Making formatted timer strings. */ #define ONE_DAY_SECOND 60*60*24 #define ONE_WEEK_SECOND 60*60*24*7 - if (now < ONE_DAY_SECOND) - snprintf (buf, buflen, "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); - else if (now < ONE_WEEK_SECOND) - snprintf (buf, buflen, "%dd%02dh%02dm", - tm->tm_yday, tm->tm_hour, tm->tm_min); - else - snprintf (buf, buflen, "%02dw%dd%02dh", - tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); - return buf; -} - -static void -zebra_show_client_detail (struct vty *vty, struct zserv *client) -{ - char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; - char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF]; - - vty_out (vty, "Client: %s", zebra_route_string(client->proto)); - if (client->instance) - vty_out (vty, " Instance: %d", client->instance); - vty_out (vty, "\n"); - - vty_out (vty, "------------------------ \n"); - vty_out (vty, "FD: %d \n", client->sock); - vty_out (vty, "Route Table ID: %d \n", client->rtm_table); - - vty_out (vty, "Connect Time: %s \n", - zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF)); - if (client->nh_reg_time) - { - vty_out (vty, "Nexthop Registry Time: %s \n", - zserv_time_buf(&client->nh_reg_time, nhbuf, ZEBRA_TIME_BUF)); - if (client->nh_last_upd_time) - vty_out (vty, "Nexthop Last Update Time: %s \n", - zserv_time_buf(&client->nh_last_upd_time, mbuf, ZEBRA_TIME_BUF)); + if (now < ONE_DAY_SECOND) + snprintf(buf, buflen, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, + tm->tm_sec); + else if (now < ONE_WEEK_SECOND) + snprintf(buf, buflen, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, + tm->tm_min); else - vty_out (vty, "No Nexthop Update sent\n"); - } - else - vty_out (vty, "Not registered for Nexthop Updates\n"); - - vty_out (vty, "Last Msg Rx Time: %s \n", - zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF)); - vty_out (vty, "Last Msg Tx Time: %s \n", - zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF)); - if (client->last_read_time) - vty_out (vty, "Last Rcvd Cmd: %s \n", - zserv_command_string(client->last_read_cmd)); - if (client->last_write_time) - vty_out (vty, "Last Sent Cmd: %s \n", - zserv_command_string(client->last_write_cmd)); - vty_out (vty, "\n"); - - vty_out (vty, "Type Add Update Del \n"); - vty_out (vty, "================================================== \n"); - vty_out (vty, "IPv4 %-12d%-12d%-12d\n", client->v4_route_add_cnt, - client->v4_route_upd8_cnt, client->v4_route_del_cnt); - vty_out (vty, "IPv6 %-12d%-12d%-12d\n", client->v6_route_add_cnt, - client->v6_route_upd8_cnt, client->v6_route_del_cnt); - vty_out (vty, "Redist:v4 %-12d%-12d%-12d\n", client->redist_v4_add_cnt, 0, - client->redist_v4_del_cnt); - vty_out (vty, "Redist:v6 %-12d%-12d%-12d\n", client->redist_v6_add_cnt, 0, - client->redist_v6_del_cnt); - vty_out (vty, "Connected %-12d%-12d%-12d\n", client->ifadd_cnt, 0, - client->ifdel_cnt); - vty_out (vty, "BFD peer %-12d%-12d%-12d\n", client->bfd_peer_add_cnt, - client->bfd_peer_upd8_cnt, client->bfd_peer_del_cnt); - vty_out (vty, "Interface Up Notifications: %d\n",client->ifup_cnt); - vty_out (vty, "Interface Down Notifications: %d\n",client->ifdown_cnt); - vty_out (vty, "VNI add notifications: %d\n", client->vniadd_cnt); - vty_out (vty, "VNI delete notifications: %d\n", client->vnidel_cnt); - vty_out (vty, "MAC-IP add notifications: %d\n", client->macipadd_cnt); - vty_out (vty, "MAC-IP delete notifications: %d\n", client->macipdel_cnt); - - vty_out (vty, "\n"); - return; -} - -static void -zebra_show_client_brief (struct vty *vty, struct zserv *client) -{ - char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; - char wbuf[ZEBRA_TIME_BUF]; - - vty_out (vty, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d\n", - zebra_route_string(client->proto), - zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF), - zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF), - zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF), - client->v4_route_add_cnt+client->v4_route_upd8_cnt, - client->v4_route_del_cnt, - client->v6_route_add_cnt+client->v6_route_upd8_cnt, - client->v6_route_del_cnt); - -} - -struct zserv * -zebra_find_client (u_char proto) -{ - struct listnode *node, *nnode; - struct zserv *client; - - for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) - { - if (client->proto == proto) - return client; - } - - return NULL; + snprintf(buf, buflen, "%02dw%dd%02dh", tm->tm_yday / 7, + tm->tm_yday - ((tm->tm_yday / 7) * 7), tm->tm_hour); + return buf; +} + +static void zebra_show_client_detail(struct vty *vty, struct zserv *client) +{ + char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; + char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF]; + + vty_out(vty, "Client: %s", zebra_route_string(client->proto)); + if (client->instance) + vty_out(vty, " Instance: %d", client->instance); + vty_out(vty, "\n"); + + vty_out(vty, "------------------------ \n"); + vty_out(vty, "FD: %d \n", client->sock); + vty_out(vty, "Route Table ID: %d \n", client->rtm_table); + + vty_out(vty, "Connect Time: %s \n", + zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF)); + if (client->nh_reg_time) { + vty_out(vty, "Nexthop Registry Time: %s \n", + zserv_time_buf(&client->nh_reg_time, nhbuf, + ZEBRA_TIME_BUF)); + if (client->nh_last_upd_time) + vty_out(vty, "Nexthop Last Update Time: %s \n", + zserv_time_buf(&client->nh_last_upd_time, mbuf, + ZEBRA_TIME_BUF)); + else + vty_out(vty, "No Nexthop Update sent\n"); + } else + vty_out(vty, "Not registered for Nexthop Updates\n"); + + vty_out(vty, "Last Msg Rx Time: %s \n", + zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF)); + vty_out(vty, "Last Msg Tx Time: %s \n", + zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF)); + if (client->last_read_time) + vty_out(vty, "Last Rcvd Cmd: %s \n", + zserv_command_string(client->last_read_cmd)); + if (client->last_write_time) + vty_out(vty, "Last Sent Cmd: %s \n", + zserv_command_string(client->last_write_cmd)); + vty_out(vty, "\n"); + + vty_out(vty, "Type Add Update Del \n"); + vty_out(vty, "================================================== \n"); + vty_out(vty, "IPv4 %-12d%-12d%-12d\n", client->v4_route_add_cnt, + client->v4_route_upd8_cnt, client->v4_route_del_cnt); + vty_out(vty, "IPv6 %-12d%-12d%-12d\n", client->v6_route_add_cnt, + client->v6_route_upd8_cnt, client->v6_route_del_cnt); + vty_out(vty, "Redist:v4 %-12d%-12d%-12d\n", client->redist_v4_add_cnt, + 0, client->redist_v4_del_cnt); + vty_out(vty, "Redist:v6 %-12d%-12d%-12d\n", client->redist_v6_add_cnt, + 0, client->redist_v6_del_cnt); + vty_out(vty, "Connected %-12d%-12d%-12d\n", client->ifadd_cnt, 0, + client->ifdel_cnt); + vty_out(vty, "BFD peer %-12d%-12d%-12d\n", client->bfd_peer_add_cnt, + client->bfd_peer_upd8_cnt, client->bfd_peer_del_cnt); + vty_out(vty, "Interface Up Notifications: %d\n", client->ifup_cnt); + vty_out(vty, "Interface Down Notifications: %d\n", client->ifdown_cnt); + vty_out(vty, "VNI add notifications: %d\n", client->vniadd_cnt); + vty_out(vty, "VNI delete notifications: %d\n", client->vnidel_cnt); + vty_out(vty, "MAC-IP add notifications: %d\n", client->macipadd_cnt); + vty_out(vty, "MAC-IP delete notifications: %d\n", client->macipdel_cnt); + + vty_out(vty, "\n"); + return; +} + +static void zebra_show_client_brief(struct vty *vty, struct zserv *client) +{ + char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; + char wbuf[ZEBRA_TIME_BUF]; + + vty_out(vty, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d\n", + zebra_route_string(client->proto), + zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF), + zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF), + zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF), + client->v4_route_add_cnt + client->v4_route_upd8_cnt, + client->v4_route_del_cnt, + client->v6_route_add_cnt + client->v6_route_upd8_cnt, + client->v6_route_del_cnt); +} + +struct zserv *zebra_find_client(u_char proto) +{ + struct listnode *node, *nnode; + struct zserv *client; + + for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + if (client->proto == proto) + return client; + } + + return NULL; } #ifdef HAVE_NETLINK @@ -2791,8 +2737,8 @@ DEFUN (show_table, SHOW_STR "default routing table to use for all clients\n") { - vty_out (vty, "table %d\n",zebrad.rtm_table_default); - return CMD_SUCCESS; + vty_out(vty, "table %d\n", zebrad.rtm_table_default); + return CMD_SUCCESS; } DEFUN (config_table, @@ -2801,8 +2747,8 @@ DEFUN (config_table, "Configure target kernel routing table\n" "TABLE integer\n") { - zebrad.rtm_table_default = strtol (argv[1]->arg, (char**)0, 10); - return CMD_SUCCESS; + zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10); + return CMD_SUCCESS; } DEFUN (no_config_table, @@ -2812,8 +2758,8 @@ DEFUN (no_config_table, "Configure target kernel routing table\n" "TABLE integer\n") { - zebrad.rtm_table_default = 0; - return CMD_SUCCESS; + zebrad.rtm_table_default = 0; + return CMD_SUCCESS; } #endif @@ -2823,19 +2769,18 @@ DEFUN (ip_forwarding, IP_STR "Turn on IP forwarding") { - int ret; + int ret; - ret = ipforward (); - if (ret == 0) - ret = ipforward_on (); + ret = ipforward(); + if (ret == 0) + ret = ipforward_on(); - if (ret == 0) - { - vty_out (vty, "Can't turn on IP forwarding\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (ret == 0) { + vty_out(vty, "Can't turn on IP forwarding\n"); + return CMD_WARNING_CONFIG_FAILED; + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ip_forwarding, @@ -2845,19 +2790,18 @@ DEFUN (no_ip_forwarding, IP_STR "Turn off IP forwarding") { - int ret; + int ret; - ret = ipforward (); - if (ret != 0) - ret = ipforward_off (); + ret = ipforward(); + if (ret != 0) + ret = ipforward_off(); - if (ret != 0) - { - vty_out (vty, "Can't turn off IP forwarding\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (ret != 0) { + vty_out(vty, "Can't turn off IP forwarding\n"); + return CMD_WARNING_CONFIG_FAILED; + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_zebra, @@ -2866,21 +2810,23 @@ DEFUN (show_zebra, SHOW_STR "Zebra information\n") { - struct vrf *vrf; + struct vrf *vrf; - vty_out (vty, - " Route Route Neighbor LSP LSP\n"); - vty_out (vty, - "VRF Installs Removals Updates Installs Removals\n"); - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) - { - struct zebra_vrf *zvrf = vrf->info; - vty_out (vty,"%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n", - vrf->name, zvrf->installs, zvrf->removals, - zvrf->neigh_updates, zvrf->lsp_installs,zvrf->lsp_removals); - } + vty_out(vty, + " Route Route Neighbor LSP LSP\n"); + vty_out(vty, + "VRF Installs Removals Updates Installs Removals\n"); + RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) + { + struct zebra_vrf *zvrf = vrf->info; + vty_out(vty, "%-25s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 + " %10" PRIu64 " %10" PRIu64 "\n", + vrf->name, zvrf->installs, zvrf->removals, + zvrf->neigh_updates, zvrf->lsp_installs, + zvrf->lsp_removals); + } - return CMD_SUCCESS; + return CMD_SUCCESS; } /* This command is for debugging purpose. */ @@ -2891,13 +2837,13 @@ DEFUN (show_zebra_client, "Zebra information\n" "Client information\n") { - struct listnode *node; - struct zserv *client; + struct listnode *node; + struct zserv *client; - for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) - zebra_show_client_detail(vty, client); + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) + zebra_show_client_detail(vty, client); - return CMD_SUCCESS; + return CMD_SUCCESS; } /* This command is for debugging purpose. */ @@ -2909,37 +2855,33 @@ DEFUN (show_zebra_client_summary, "Client information brief\n" "Brief Summary\n") { - struct listnode *node; - struct zserv *client; + struct listnode *node; + struct zserv *client; - vty_out (vty, - "Name Connect Time Last Read Last Write IPv4 Routes IPv6 Routes \n"); - vty_out (vty, - "--------------------------------------------------------------------------------\n"); + vty_out(vty, + "Name Connect Time Last Read Last Write IPv4 Routes IPv6 Routes \n"); + vty_out(vty, + "--------------------------------------------------------------------------------\n"); - for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) - zebra_show_client_brief(vty, client); + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) + zebra_show_client_brief(vty, client); - vty_out (vty, "Routes column shows (added+updated)/deleted\n"); - return CMD_SUCCESS; + vty_out(vty, "Routes column shows (added+updated)/deleted\n"); + return CMD_SUCCESS; } /* Table configuration write function. */ -static int -config_write_table (struct vty *vty) +static int config_write_table(struct vty *vty) { - if (zebrad.rtm_table_default) - vty_out (vty, "table %d\n",zebrad.rtm_table_default); - return 0; + if (zebrad.rtm_table_default) + vty_out(vty, "table %d\n", zebrad.rtm_table_default); + return 0; } /* table node for routing tables. */ -static struct cmd_node table_node = -{ - TABLE_NODE, - "", /* This node has no interface. */ - 1 -}; +static struct cmd_node table_node = {TABLE_NODE, + "", /* This node has no interface. */ + 1}; /* Only display ip forwarding is enabled or not. */ DEFUN (show_ip_forwarding, @@ -2949,15 +2891,15 @@ DEFUN (show_ip_forwarding, IP_STR "IP forwarding status\n") { - int ret; + int ret; - ret = ipforward (); + ret = ipforward(); - if (ret == 0) - vty_out (vty, "IP forwarding is off\n"); - else - vty_out (vty, "IP forwarding is on\n"); - return CMD_SUCCESS; + if (ret == 0) + vty_out(vty, "IP forwarding is off\n"); + else + vty_out(vty, "IP forwarding is on\n"); + return CMD_SUCCESS; } /* Only display ipv6 forwarding is enabled or not. */ @@ -2968,26 +2910,25 @@ DEFUN (show_ipv6_forwarding, "IPv6 information\n" "Forwarding status\n") { - int ret; + int ret; - ret = ipforward_ipv6 (); + ret = ipforward_ipv6(); - switch (ret) - { - case -1: - vty_out (vty, "ipv6 forwarding is unknown\n"); - break; - case 0: - vty_out (vty, "ipv6 forwarding is %s\n", "off"); - break; - case 1: - vty_out (vty, "ipv6 forwarding is %s\n", "on"); - break; - default: - vty_out (vty, "ipv6 forwarding is %s\n", "off"); - break; - } - return CMD_SUCCESS; + switch (ret) { + case -1: + vty_out(vty, "ipv6 forwarding is unknown\n"); + break; + case 0: + vty_out(vty, "ipv6 forwarding is %s\n", "off"); + break; + case 1: + vty_out(vty, "ipv6 forwarding is %s\n", "on"); + break; + default: + vty_out(vty, "ipv6 forwarding is %s\n", "off"); + break; + } + return CMD_SUCCESS; } DEFUN (ipv6_forwarding, @@ -2996,19 +2937,18 @@ DEFUN (ipv6_forwarding, IPV6_STR "Turn on IPv6 forwarding") { - int ret; + int ret; - ret = ipforward_ipv6 (); - if (ret == 0) - ret = ipforward_ipv6_on (); + ret = ipforward_ipv6(); + if (ret == 0) + ret = ipforward_ipv6_on(); - if (ret == 0) - { - vty_out (vty, "Can't turn on IPv6 forwarding\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (ret == 0) { + vty_out(vty, "Can't turn on IPv6 forwarding\n"); + return CMD_WARNING_CONFIG_FAILED; + } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (no_ipv6_forwarding, @@ -3018,83 +2958,76 @@ DEFUN (no_ipv6_forwarding, IPV6_STR "Turn off IPv6 forwarding") { - int ret; + int ret; - ret = ipforward_ipv6 (); - if (ret != 0) - ret = ipforward_ipv6_off (); + ret = ipforward_ipv6(); + if (ret != 0) + ret = ipforward_ipv6_off(); - if (ret != 0) - { - vty_out (vty, "Can't turn off IPv6 forwarding\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (ret != 0) { + vty_out(vty, "Can't turn off IPv6 forwarding\n"); + return CMD_WARNING_CONFIG_FAILED; + } - return CMD_SUCCESS; + return CMD_SUCCESS; } /* IPForwarding configuration write function. */ -static int -config_write_forwarding (struct vty *vty) +static int config_write_forwarding(struct vty *vty) { - /* FIXME: Find better place for that. */ - router_id_write (vty); + /* FIXME: Find better place for that. */ + router_id_write(vty); - if (!ipforward ()) - vty_out (vty, "no ip forwarding\n"); - if (!ipforward_ipv6 ()) - vty_out (vty, "no ipv6 forwarding\n"); - vty_out (vty, "!\n"); - return 0; + if (!ipforward()) + vty_out(vty, "no ip forwarding\n"); + if (!ipforward_ipv6()) + vty_out(vty, "no ipv6 forwarding\n"); + vty_out(vty, "!\n"); + return 0; } /* table node for routing tables. */ -static struct cmd_node forwarding_node = -{ - FORWARDING_NODE, - "", /* This node has no interface. */ - 1 -}; +static struct cmd_node forwarding_node = {FORWARDING_NODE, + "", /* This node has no interface. */ + 1}; /* Initialisation of zebra and installation of commands. */ -void -zebra_init (void) +void zebra_init(void) { - /* Client list init. */ - zebrad.client_list = list_new (); + /* Client list init. */ + zebrad.client_list = list_new(); - /* Install configuration write function. */ - install_node (&table_node, config_write_table); - install_node (&forwarding_node, config_write_forwarding); + /* Install configuration write function. */ + install_node(&table_node, config_write_table); + install_node(&forwarding_node, config_write_forwarding); - install_element (VIEW_NODE, &show_ip_forwarding_cmd); - install_element (CONFIG_NODE, &ip_forwarding_cmd); - install_element (CONFIG_NODE, &no_ip_forwarding_cmd); - install_element (ENABLE_NODE, &show_zebra_cmd); - install_element (ENABLE_NODE, &show_zebra_client_cmd); - install_element (ENABLE_NODE, &show_zebra_client_summary_cmd); + install_element(VIEW_NODE, &show_ip_forwarding_cmd); + install_element(CONFIG_NODE, &ip_forwarding_cmd); + install_element(CONFIG_NODE, &no_ip_forwarding_cmd); + install_element(ENABLE_NODE, &show_zebra_cmd); + install_element(ENABLE_NODE, &show_zebra_client_cmd); + install_element(ENABLE_NODE, &show_zebra_client_summary_cmd); #ifdef HAVE_NETLINK - install_element (VIEW_NODE, &show_table_cmd); - install_element (CONFIG_NODE, &config_table_cmd); - install_element (CONFIG_NODE, &no_config_table_cmd); + install_element(VIEW_NODE, &show_table_cmd); + install_element(CONFIG_NODE, &config_table_cmd); + install_element(CONFIG_NODE, &no_config_table_cmd); #endif /* HAVE_NETLINK */ - install_element (VIEW_NODE, &show_ipv6_forwarding_cmd); - install_element (CONFIG_NODE, &ipv6_forwarding_cmd); - install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd); + install_element(VIEW_NODE, &show_ipv6_forwarding_cmd); + install_element(CONFIG_NODE, &ipv6_forwarding_cmd); + install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd); - /* Route-map */ - zebra_route_map_init (); + /* Route-map */ + zebra_route_map_init(); } /* Make zebra server socket, wiping any existing one (see bug #403). */ -void -zebra_zserv_socket_init (char *path) +void zebra_zserv_socket_init(char *path) { #ifdef HAVE_TCP_ZEBRA - zebra_serv (); + zebra_serv(); #else - zebra_serv_un (path ? path : ZEBRA_SERV_PATH); + zebra_serv_un(path ? path : ZEBRA_SERV_PATH); #endif /* HAVE_TCP_ZEBRA */ } |