summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/buffer.h26
-rw-r--r--lib/compiler.h4
-rw-r--r--lib/if.c38
-rw-r--r--lib/if.h67
-rw-r--r--lib/prefix.h26
-rw-r--r--lib/sockunion.h34
-rw-r--r--lib/workqueue.c30
-rw-r--r--lib/workqueue.h21
8 files changed, 136 insertions, 110 deletions
diff --git a/lib/buffer.h b/lib/buffer.h
index 5d98c31dbc..a0b82d2121 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/compiler.h b/lib/compiler.h
index 0a54c02d20..617b0c265b 100644
--- a/lib/compiler.h
+++ b/lib/compiler.h
@@ -424,10 +424,10 @@ _Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8,
* type.)
*/
#ifndef __cplusplus
-#define prefixtype(uname, typename, fieldname) typename *fieldname;
+#define uniontype(uname, typename, fieldname) typename *fieldname;
#define TRANSPARENT_UNION __attribute__((transparent_union))
#else
-#define prefixtype(uname, typename, fieldname) \
+#define uniontype(uname, typename, fieldname) \
typename *fieldname; \
uname(typename *x) \
{ \
diff --git a/lib/if.c b/lib/if.c
index 48c01af882..9e9cbd53a4 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -42,15 +42,14 @@ RB_GENERATE(if_index_head, interface, index_entry, if_cmp_index_func);
DEFINE_QOBJ_TYPE(interface);
-DEFINE_HOOK(if_add, (struct interface * ifp), (ifp));
-DEFINE_KOOH(if_del, (struct interface * ifp), (ifp));
+DEFINE_HOOK(if_add, (struct interface *ifp), (ifp));
+DEFINE_KOOH(if_del, (struct interface *ifp), (ifp));
-static struct interface_master{
- int (*create_hook)(struct interface *ifp);
- int (*up_hook)(struct interface *ifp);
- int (*down_hook)(struct interface *ifp);
- int (*destroy_hook)(struct interface *ifp);
-} ifp_master = { 0, };
+DEFINE_HOOK(if_real, (struct interface *ifp), (ifp));
+DEFINE_KOOH(if_unreal, (struct interface *ifp), (ifp));
+
+DEFINE_HOOK(if_up, (struct interface *ifp), (ifp));
+DEFINE_KOOH(if_down, (struct interface *ifp), (ifp));
/* Compare interface names, returning an integer greater than, equal to, or
* less than 0, (following the strcmp convention), according to the
@@ -180,14 +179,12 @@ static struct interface *if_new(struct vrf *vrf)
void if_new_via_zapi(struct interface *ifp)
{
- if (ifp_master.create_hook)
- (*ifp_master.create_hook)(ifp);
+ hook_call(if_real, ifp);
}
void if_destroy_via_zapi(struct interface *ifp)
{
- if (ifp_master.destroy_hook)
- (*ifp_master.destroy_hook)(ifp);
+ hook_call(if_unreal, ifp);
ifp->oldifindex = ifp->ifindex;
if_set_index(ifp, IFINDEX_INTERNAL);
@@ -198,14 +195,12 @@ void if_destroy_via_zapi(struct interface *ifp)
void if_up_via_zapi(struct interface *ifp)
{
- if (ifp_master.up_hook)
- (*ifp_master.up_hook)(ifp);
+ hook_call(if_up, ifp);
}
void if_down_via_zapi(struct interface *ifp)
{
- if (ifp_master.down_hook)
- (*ifp_master.down_hook)(ifp);
+ hook_call(if_down, ifp);
}
static struct interface *if_create_name(const char *name, struct vrf *vrf)
@@ -1477,17 +1472,6 @@ void if_cmd_init_default(void)
if_cmd_init(if_nb_config_write);
}
-void if_zapi_callbacks(int (*create)(struct interface *ifp),
- int (*up)(struct interface *ifp),
- int (*down)(struct interface *ifp),
- int (*destroy)(struct interface *ifp))
-{
- ifp_master.create_hook = create;
- ifp_master.up_hook = up;
- ifp_master.down_hook = down;
- ifp_master.destroy_hook = destroy;
-}
-
/* ------- Northbound callbacks ------- */
/*
diff --git a/lib/if.h b/lib/if.h
index f93f0e70b8..868766d645 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -386,8 +386,27 @@ DECLARE_QOBJ_TYPE(interface);
* can use 1000+ so they run after the daemon has initialised daemon-specific
* interface data
*/
-DECLARE_HOOK(if_add, (struct interface * ifp), (ifp));
-DECLARE_KOOH(if_del, (struct interface * ifp), (ifp));
+DECLARE_HOOK(if_add, (struct interface *ifp), (ifp));
+DECLARE_KOOH(if_del, (struct interface *ifp), (ifp));
+
+/* called (in daemons) when ZAPI tells us the interface actually exists
+ * (ifindex != IFINDEX_INTERNAL)
+ *
+ * WARNING: these 2 hooks NEVER CALLED inside zebra!
+ */
+DECLARE_HOOK(if_real, (struct interface *ifp), (ifp));
+DECLARE_KOOH(if_unreal, (struct interface *ifp), (ifp));
+
+/* called (in daemons) on state changes on interfaces. Whether this is admin
+ * state (= pure config) or carrier state (= hardware link plugged) depends on
+ * zebra's "link-detect" configuration. By default, it's carrier state, so
+ * this won't happen until the interface actually has a link.
+ *
+ * WARNING: these 2 hooks NEVER CALLED inside zebra!
+ */
+DECLARE_HOOK(if_up, (struct interface *ifp), (ifp));
+DECLARE_KOOH(if_down, (struct interface *ifp), (ifp));
+
#define METRIC_MAX (~0)
@@ -512,9 +531,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 +564,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 +582,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 +598,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 +619,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;
@@ -609,10 +630,6 @@ extern void if_vty_config_start(struct vty *vty, struct interface *ifp);
extern void if_vty_config_end(struct vty *vty);
extern void if_cmd_init(int (*config_write)(struct vty *));
extern void if_cmd_init_default(void);
-extern void if_zapi_callbacks(int (*create)(struct interface *ifp),
- int (*up)(struct interface *ifp),
- int (*down)(struct interface *ifp),
- int (*destroy)(struct interface *ifp));
extern void if_new_via_zapi(struct interface *ifp);
extern void if_up_via_zapi(struct interface *ifp);
diff --git a/lib/prefix.h b/lib/prefix.h
index fc6e32dd54..14f2695933 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -286,23 +286,25 @@ struct prefix_sg {
struct in_addr grp;
};
+/* clang-format off */
union prefixptr {
- prefixtype(prefixptr, struct prefix, p)
- prefixtype(prefixptr, struct prefix_ipv4, p4)
- prefixtype(prefixptr, struct prefix_ipv6, p6)
- prefixtype(prefixptr, struct prefix_evpn, evp)
- prefixtype(prefixptr, struct prefix_fs, fs)
- prefixtype(prefixptr, struct prefix_rd, rd)
+ uniontype(prefixptr, struct prefix, p)
+ uniontype(prefixptr, struct prefix_ipv4, p4)
+ uniontype(prefixptr, struct prefix_ipv6, p6)
+ uniontype(prefixptr, struct prefix_evpn, evp)
+ uniontype(prefixptr, struct prefix_fs, fs)
+ uniontype(prefixptr, struct prefix_rd, rd)
} TRANSPARENT_UNION;
union prefixconstptr {
- prefixtype(prefixconstptr, const struct prefix, p)
- prefixtype(prefixconstptr, const struct prefix_ipv4, p4)
- prefixtype(prefixconstptr, const struct prefix_ipv6, p6)
- prefixtype(prefixconstptr, const struct prefix_evpn, evp)
- prefixtype(prefixconstptr, const struct prefix_fs, fs)
- prefixtype(prefixconstptr, const struct prefix_rd, rd)
+ uniontype(prefixconstptr, const struct prefix, p)
+ uniontype(prefixconstptr, const struct prefix_ipv4, p4)
+ uniontype(prefixconstptr, const struct prefix_ipv6, p6)
+ uniontype(prefixconstptr, const struct prefix_evpn, evp)
+ uniontype(prefixconstptr, const struct prefix_fs, fs)
+ uniontype(prefixconstptr, const struct prefix_rd, rd)
} TRANSPARENT_UNION;
+/* clang-format on */
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
diff --git a/lib/sockunion.h b/lib/sockunion.h
index e507255999..675855e2b6 100644
--- a/lib/sockunion.h
+++ b/lib/sockunion.h
@@ -7,6 +7,8 @@
#ifndef _ZEBRA_SOCKUNION_H
#define _ZEBRA_SOCKUNION_H
+#include "compiler.h"
+
#include "privs.h"
#include "if.h"
#include <sys/un.h>
@@ -27,8 +29,40 @@ union sockunion {
struct sockaddr_mpls smpls;
struct sockaddr_rtlabel rtlabel;
#endif
+
+ /* sockaddr_storage is guaranteed to be larger than the others */
+ struct sockaddr_storage sa_storage;
};
+/* clang-format off */
+/* for functions that want to accept any sockaddr pointer without casts */
+union sockaddrptr {
+ uniontype(sockaddrptr, union sockunion, su)
+ uniontype(sockaddrptr, struct sockaddr, sa)
+ uniontype(sockaddrptr, struct sockaddr_in, sin)
+ uniontype(sockaddrptr, struct sockaddr_in6, sin6)
+ uniontype(sockaddrptr, struct sockaddr_un, sun)
+#ifdef __OpenBSD__
+ uniontype(sockaddrptr, struct sockaddr_mpls, smpls)
+ uniontype(sockaddrptr, struct sockaddr_rtlabel, rtlabel)
+#endif
+ uniontype(sockaddrptr, struct sockaddr_storage, sa_storage)
+} TRANSPARENT_UNION;
+
+union sockaddrconstptr {
+ uniontype(sockaddrconstptr, const union sockunion, su)
+ uniontype(sockaddrconstptr, const struct sockaddr, sa)
+ uniontype(sockaddrconstptr, const struct sockaddr_in, sin)
+ uniontype(sockaddrconstptr, const struct sockaddr_in6, sin6)
+ uniontype(sockaddrconstptr, const struct sockaddr_un, sun)
+#ifdef __OpenBSD__
+ uniontype(sockaddrconstptr, const struct sockaddr_mpls, smpls)
+ uniontype(sockaddrconstptr, const struct sockaddr_rtlabel, rtlabel)
+#endif
+ uniontype(sockaddrconstptr, const struct sockaddr_storage, sa_storage)
+} TRANSPARENT_UNION;
+/* clang-format on */
+
enum connect_result { connect_error, connect_success, connect_in_progress };
/* Default address family. */
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 2281c4c369..d630af1d1d 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;
@@ -265,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: {
@@ -276,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);
@@ -296,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);
@@ -352,8 +359,7 @@ stats:
/* 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 5d84739d5c..a495fe8615 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.. */
@@ -117,22 +115,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
@@ -160,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