From a22ab3f98f96908dc1bf7b7ad675e0005193d8e5 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 29 Oct 2023 16:04:16 -0400 Subject: [PATCH 1/4] zebra: Fix missing break in switch Recent Changes added the -Wimplicit-fallthrough flag to FRR's compilation. Implementor does not build with lua support and as such this one was missed in the compilation Signed-off-by: Donald Sharp --- zebra/zebra_script.c | 1 + 1 file changed, 1 insertion(+) diff --git a/zebra/zebra_script.c b/zebra/zebra_script.c index 9f8490ac66ff..3ebc6d974bb8 100644 --- a/zebra/zebra_script.c +++ b/zebra/zebra_script.c @@ -396,6 +396,7 @@ void lua_pushzebra_dplane_ctx(lua_State *L, const struct zebra_dplane_ctx *ctx) lua_setfield(L, -2, "mtu"); } lua_setfield(L, -2, "gre"); + break; case DPLANE_OP_ADDR_INSTALL: case DPLANE_OP_ADDR_UNINSTALL: From a553bd6d68a9f37a7194e9bb03027fa3e511f2e2 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 29 Oct 2023 16:13:21 -0400 Subject: [PATCH 2/4] lib: Move workqueue private functions into workqueue.c Some Functions are not used outside of workqueue.c. Move them inside of workqueue.c to limit scope. Signed-off-by: Donald Sharp --- lib/workqueue.c | 16 ++++++++++++++++ lib/workqueue.h | 16 ---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/workqueue.c b/lib/workqueue.c index 2281c4c369c0..e87edef68bdf 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -42,6 +42,15 @@ static void work_queue_item_free(struct work_queue_item *item) return; } +static inline void work_queue_item_dequeue(struct work_queue *wq, + struct work_queue_item *item) +{ + assert(wq->item_count > 0); + + wq->item_count--; + STAILQ_REMOVE(&wq->items, item, work_queue_item, wq); +} + static void work_queue_item_remove(struct work_queue *wq, struct work_queue_item *item) { @@ -133,6 +142,13 @@ static int work_queue_schedule(struct work_queue *wq, unsigned int delay) return 0; } +static inline void work_queue_item_enqueue(struct work_queue *wq, + struct work_queue_item *item) +{ + STAILQ_INSERT_TAIL(&wq->items, item, wq); + wq->item_count++; +} + void work_queue_add(struct work_queue *wq, void *data) { struct work_queue_item *item; diff --git a/lib/workqueue.h b/lib/workqueue.h index 5d84739d5c6b..8b340ce53279 100644 --- a/lib/workqueue.h +++ b/lib/workqueue.h @@ -117,22 +117,6 @@ work_queue_last_item(struct work_queue *wq) return STAILQ_LAST(&wq->items, work_queue_item, wq); } -static inline void work_queue_item_enqueue(struct work_queue *wq, - struct work_queue_item *item) -{ - STAILQ_INSERT_TAIL(&wq->items, item, wq); - wq->item_count++; -} - -static inline void work_queue_item_dequeue(struct work_queue *wq, - struct work_queue_item *item) -{ - assert(wq->item_count > 0); - - wq->item_count--; - STAILQ_REMOVE(&wq->items, item, work_queue_item, wq); -} - /* create a new work queue, of given name. * user must fill in the spec of the returned work queue before adding * anything to it From b14f75540892e2e90ca4f8d9ae8c2a31c6d32681 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 29 Oct 2023 16:56:27 -0400 Subject: [PATCH 3/4] lib: Cleanup some header files in lib buffer.h -> Bring up to our standard if.h -> Bring up to our standard workqueue.h -> expand documentation slightly Signed-off-by: Donald Sharp --- lib/buffer.h | 26 +++++++++++++------------- lib/if.h | 40 +++++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/lib/buffer.h b/lib/buffer.h index 5d98c31dbc4c..a0b82d2121c3 100644 --- a/lib/buffer.h +++ b/lib/buffer.h @@ -14,21 +14,21 @@ extern "C" { /* Create a new buffer. Memory will be allocated in chunks of the given size. If the argument is 0, the library will supply a reasonable default size suitable for buffering socket I/O. */ -extern struct buffer *buffer_new(size_t); +extern struct buffer *buffer_new(size_t size); /* Free all data in the buffer. */ -extern void buffer_reset(struct buffer *); +extern void buffer_reset(struct buffer *b); /* This function first calls buffer_reset to release all buffered data. Then it frees the struct buffer itself. */ -extern void buffer_free(struct buffer *); +extern void buffer_free(struct buffer *b); /* Add the given data to the end of the buffer. */ -extern void buffer_put(struct buffer *, const void *, size_t); +extern void buffer_put(struct buffer *b, const void *p, size_t size); /* Add a single character to the end of the buffer. */ -extern void buffer_putc(struct buffer *, uint8_t); +extern void buffer_putc(struct buffer *b, uint8_t c); /* Add a NUL-terminated string to the end of the buffer. */ -extern void buffer_putstr(struct buffer *, const char *); +extern void buffer_putstr(struct buffer *b, const char *str); /* Add given data, inline-expanding \n to \r\n */ extern void buffer_put_crlf(struct buffer *b, const void *p, size_t size); @@ -36,10 +36,10 @@ extern void buffer_put_crlf(struct buffer *b, const void *p, size_t size); single NUL-terminated string allocated using XMALLOC(MTYPE_TMP). Note that this function does not alter the state of the buffer, so the data is still inside waiting to be flushed. */ -char *buffer_getstr(struct buffer *); +char *buffer_getstr(struct buffer *b); /* Returns 1 if there is no pending data in the buffer. Otherwise returns 0. */ -int buffer_empty(struct buffer *); +int buffer_empty(struct buffer *b); typedef enum { /* An I/O error occurred. The buffer should be destroyed and the @@ -59,12 +59,12 @@ typedef enum { /* Try to write this data to the file descriptor. Any data that cannot be written immediately is added to the buffer queue. */ -extern buffer_status_t buffer_write(struct buffer *, int fd, const void *, - size_t); +extern buffer_status_t buffer_write(struct buffer *b, int fd, const void *p, + size_t size); /* This function attempts to flush some (but perhaps not all) of the queued data to the given file descriptor. */ -extern buffer_status_t buffer_flush_available(struct buffer *, int fd); +extern buffer_status_t buffer_flush_available(struct buffer *b, int fd); /* The following 2 functions (buffer_flush_all and buffer_flush_window) are for use in lib/vty.c only. They should not be used elsewhere. */ @@ -72,7 +72,7 @@ extern buffer_status_t buffer_flush_available(struct buffer *, int fd); /* Call buffer_flush_available repeatedly until either all data has been flushed, or an I/O error has been encountered, or the operation would block. */ -extern buffer_status_t buffer_flush_all(struct buffer *, int fd); +extern buffer_status_t buffer_flush_all(struct buffer *b, int fd); /* Attempt to write enough data to the given fd to fill a window of the given width and height (and remove the data written from the buffer). @@ -85,7 +85,7 @@ extern buffer_status_t buffer_flush_all(struct buffer *, int fd); to return -1 (because the logic for handling the erase and more features is too complicated to retry the write later). */ -extern buffer_status_t buffer_flush_window(struct buffer *, int fd, int width, +extern buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width, int height, int erase, int no_more); #ifdef __cplusplus diff --git a/lib/if.h b/lib/if.h index f93f0e70b87a..4503d05fb29c 100644 --- a/lib/if.h +++ b/lib/if.h @@ -512,9 +512,9 @@ extern int if_cmp_name_func(const char *p1, const char *p2); * This is useful for vrf route-leaking. So more than anything * else think before you use VRF_UNKNOWN */ -extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id); +extern void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id); -extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id); +extern struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id); extern struct interface *if_vrf_lookup_by_index_next(ifindex_t ifindex, vrf_id_t vrf_id); extern struct interface *if_lookup_address_local(const void *matchaddr, @@ -545,7 +545,7 @@ extern int if_set_index(struct interface *ifp, ifindex_t ifindex); /* Delete the interface, but do not free the structure, and leave it in the interface list. It is often advisable to leave the pseudo interface structure because there may be configuration information attached. */ -extern void if_delete_retain(struct interface *); +extern void if_delete_retain(struct interface *ifp); /* Delete and free the interface structure: calls if_delete_retain and then deletes it from the interface list and frees the structure. */ @@ -563,13 +563,13 @@ extern int if_is_pointopoint(const struct interface *ifp); extern int if_is_multicast(const struct interface *ifp); extern void if_terminate(struct vrf *vrf); extern void if_dump_all(void); -extern const char *if_flag_dump(unsigned long); -extern const char *if_link_type_str(enum zebra_link_type); +extern const char *if_flag_dump(unsigned long flags); +extern const char *if_link_type_str(enum zebra_link_type zlt); /* Please use ifindex2ifname instead of if_indextoname where possible; ifindex2ifname uses internal interface info, whereas if_indextoname must make a system call. */ -extern const char *ifindex2ifname(ifindex_t, vrf_id_t vrf_id); +extern const char *ifindex2ifname(ifindex_t ifindex, vrf_id_t vrf_id); /* Please use ifname2ifindex instead of if_nametoindex where possible; ifname2ifindex uses internal interface info, whereas if_nametoindex must @@ -579,18 +579,20 @@ extern ifindex_t ifname2ifindex(const char *ifname, vrf_id_t vrf_id); /* Connected address functions. */ extern struct connected *connected_new(void); extern void connected_free(struct connected **connected); -extern struct connected * -connected_add_by_prefix(struct interface *, struct prefix *, struct prefix *); -extern struct connected *connected_delete_by_prefix(struct interface *, - struct prefix *); -extern struct connected *connected_lookup_prefix(struct interface *, - const struct prefix *); -extern struct connected *connected_lookup_prefix_exact(struct interface *, - const struct prefix *); -extern unsigned int connected_count_by_family(struct interface *, int family); +extern struct connected *connected_add_by_prefix(struct interface *ifp, + struct prefix *p, + struct prefix *dest); +extern struct connected *connected_delete_by_prefix(struct interface *ifp, + struct prefix *p); +extern struct connected *connected_lookup_prefix(struct interface *ifp, + const struct prefix *p); +extern struct connected *connected_lookup_prefix_exact(struct interface *ifp, + const struct prefix *p); +extern unsigned int connected_count_by_family(struct interface *ifp, int family); extern struct nbr_connected *nbr_connected_new(void); -extern void nbr_connected_free(struct nbr_connected *); -struct nbr_connected *nbr_connected_check(struct interface *, struct prefix *); +extern void nbr_connected_free(struct nbr_connected *connected); +struct nbr_connected *nbr_connected_check(struct interface *ifp, + struct prefix *p); struct connected *connected_get_linklocal(struct interface *ifp); /* link parameters */ @@ -598,10 +600,10 @@ bool if_link_params_cmp(struct if_link_params *iflp1, struct if_link_params *iflp2); void if_link_params_copy(struct if_link_params *dst, struct if_link_params *src); -struct if_link_params *if_link_params_get(struct interface *); +struct if_link_params *if_link_params_get(struct interface *ifp); struct if_link_params *if_link_params_enable(struct interface *ifp); struct if_link_params *if_link_params_init(struct interface *ifp); -void if_link_params_free(struct interface *); +void if_link_params_free(struct interface *ifp); /* Northbound. */ struct vty; From 2a65f05d77f88f96d4385040d01492e805e1cc44 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 2 Nov 2023 19:17:48 -0400 Subject: [PATCH 4/4] lib: Remove unused WQ_RETRY_XXX enums These enum's have been around since 2005 and FRR still does not have any users of these particular values. After almost 20 years, let's simplify the code slightly and remove them. Signed-off-by: Donald Sharp --- lib/workqueue.c | 14 ++------------ lib/workqueue.h | 5 ++--- tests/lib/test_heavy_wq.c | 6 ------ 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/lib/workqueue.c b/lib/workqueue.c index e87edef68bdf..d630af1d1db0 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -281,8 +281,7 @@ void work_queue_run(struct event *thread) do { ret = wq->spec.workfunc(wq, item->data); item->ran++; - } while ((ret == WQ_RETRY_NOW) - && (item->ran < wq->spec.max_retries)); + } while (item->ran < wq->spec.max_retries); switch (ret) { case WQ_QUEUE_BLOCKED: { @@ -292,9 +291,6 @@ void work_queue_run(struct event *thread) item->ran--; goto stats; } - case WQ_RETRY_LATER: { - goto stats; - } case WQ_REQUEUE: { item->ran--; work_queue_item_requeue(wq, item); @@ -312,11 +308,6 @@ void work_queue_run(struct event *thread) titem = item; break; } - case WQ_RETRY_NOW: - /* a RETRY_NOW that gets here has exceeded max_tries, same - * as ERROR - */ - fallthrough; case WQ_SUCCESS: default: { work_queue_item_remove(wq, item); @@ -368,8 +359,7 @@ void work_queue_run(struct event *thread) /* Is the queue done yet? If it is, call the completion callback. */ if (!work_queue_empty(wq)) { - if (ret == WQ_RETRY_LATER || - ret == WQ_QUEUE_BLOCKED) + if (ret == WQ_QUEUE_BLOCKED) work_queue_schedule(wq, wq->spec.retry); else work_queue_schedule(wq, 0); diff --git a/lib/workqueue.h b/lib/workqueue.h index 8b340ce53279..a495fe86156c 100644 --- a/lib/workqueue.h +++ b/lib/workqueue.h @@ -26,9 +26,7 @@ DECLARE_MTYPE(WORK_QUEUE); /* action value, for use by item processor and item error handlers */ typedef enum { WQ_SUCCESS = 0, - WQ_RETRY_NOW, /* retry immediately */ - WQ_RETRY_LATER, /* retry later, cease processing work queue */ - WQ_REQUEUE, /* requeue item, continue processing work queue */ + WQ_REQUEUE, /* requeue item, continue processing work queue */ WQ_QUEUE_BLOCKED, /* Queue cant be processed at this time. * Similar to WQ_RETRY_LATER, but doesn't penalise * the particular item.. */ @@ -144,6 +142,7 @@ bool work_queue_is_scheduled(struct work_queue *wq); /* Helpers, exported for thread.c and command.c */ extern void work_queue_run(struct event *thread); +/* Function to initialize the workqueue cli */ extern void workqueue_cmd_init(void); #ifdef __cplusplus diff --git a/tests/lib/test_heavy_wq.c b/tests/lib/test_heavy_wq.c index 225573ae92f6..8c2765cfdfa2 100644 --- a/tests/lib/test_heavy_wq.c +++ b/tests/lib/test_heavy_wq.c @@ -76,12 +76,6 @@ static wq_item_status slow_func(struct work_queue *wq, void *data) for (j = 0; j < 300; j++) x += sin(x) * j; - if ((hn->i % ITERS_LATER) == 0) - return WQ_RETRY_LATER; - - if ((hn->i % ITERS_ERR) == 0) - return WQ_RETRY_NOW; - if ((hn->i % ITERS_PRINT) == 0) printf("%s did %d, x = %g\n", hn->str, hn->i, x);