diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/command.h | 2 | ||||
| -rw-r--r-- | lib/event.c | 116 | ||||
| -rw-r--r-- | lib/frrevent.h | 6 | ||||
| -rw-r--r-- | lib/prefix.h | 40 | ||||
| -rw-r--r-- | lib/srv6.h | 55 |
5 files changed, 129 insertions, 90 deletions
diff --git a/lib/command.h b/lib/command.h index 3167c652c5..718d34b007 100644 --- a/lib/command.h +++ b/lib/command.h @@ -172,6 +172,8 @@ enum node_type { OPENFABRIC_NODE, /* OpenFabric router configuration node */ VRRP_NODE, /* VRRP node */ BMP_NODE, /* BMP config under router bgp */ + ISIS_SRV6_NODE, /* ISIS SRv6 node */ + ISIS_SRV6_NODE_MSD_NODE, /* ISIS SRv6 Node MSDs node */ NODE_TYPE_MAX, /* maximum */ }; /* clang-format on */ diff --git a/lib/event.c b/lib/event.c index 4b4ca9d7ea..37a30d2511 100644 --- a/lib/event.c +++ b/lib/event.c @@ -89,34 +89,41 @@ unsigned long walltime_threshold = CONSUMED_TIME_CHECK; /* CLI start ---------------------------------------------------------------- */ #include "lib/event_clippy.c" -static unsigned int cpu_record_hash_key(const struct cpu_event_history *a) +static uint32_t cpu_record_hash_key(const struct cpu_event_history *a) { int size = sizeof(a->func); return jhash(&a->func, size, 0); } -static bool cpu_record_hash_cmp(const struct cpu_event_history *a, - const struct cpu_event_history *b) +static int cpu_record_hash_cmp(const struct cpu_event_history *a, + const struct cpu_event_history *b) { - return a->func == b->func; + return numcmp((uintptr_t)a->func, (uintptr_t)b->func); } -static void *cpu_record_hash_alloc(struct cpu_event_history *a) +DECLARE_HASH(cpu_records, struct cpu_event_history, item, cpu_record_hash_cmp, + cpu_record_hash_key); + +static struct cpu_event_history *cpu_records_get(struct event_loop *loop, + void (*func)(struct event *e), + const char *funcname) { - struct cpu_event_history *new; + struct cpu_event_history ref = { .func = func }, *res; - new = XCALLOC(MTYPE_EVENT_STATS, sizeof(struct cpu_event_history)); - new->func = a->func; - new->funcname = a->funcname; - return new; + res = cpu_records_find(loop->cpu_records, &ref); + if (!res) { + res = XCALLOC(MTYPE_EVENT_STATS, sizeof(*res)); + res->func = func; + res->funcname = funcname; + cpu_records_add(loop->cpu_records, res); + } + return res; } -static void cpu_record_hash_free(void *a) +static void cpu_records_free(struct cpu_event_history **p) { - struct cpu_event_history *hist = a; - - XFREE(MTYPE_EVENT_STATS, hist); + XFREE(MTYPE_EVENT_STATS, *p); } static void vty_out_cpu_event_history(struct vty *vty, @@ -136,14 +143,11 @@ static void vty_out_cpu_event_history(struct vty *vty, a->types & (1 << EVENT_EXECUTE) ? 'X' : ' ', a->funcname); } -static void cpu_record_hash_print(struct hash_bucket *bucket, void *args[]) +static void cpu_record_print_one(struct vty *vty, uint8_t filter, + struct cpu_event_history *totals, + const struct cpu_event_history *a) { - struct cpu_event_history *totals = args[0]; struct cpu_event_history copy; - struct vty *vty = args[1]; - uint8_t *filter = args[2]; - - struct cpu_event_history *a = bucket->data; copy.total_active = atomic_load_explicit(&a->total_active, memory_order_seq_cst); @@ -165,7 +169,7 @@ static void cpu_record_hash_print(struct hash_bucket *bucket, void *args[]) copy.types = atomic_load_explicit(&a->types, memory_order_seq_cst); copy.funcname = a->funcname; - if (!(copy.types & *filter)) + if (!(copy.types & filter)) return; vty_out_cpu_event_history(vty, ©); @@ -185,7 +189,6 @@ static void cpu_record_hash_print(struct hash_bucket *bucket, void *args[]) static void cpu_record_print(struct vty *vty, uint8_t filter) { struct cpu_event_history tmp; - void *args[3] = {&tmp, vty, &filter}; struct event_loop *m; struct listnode *ln; @@ -222,13 +225,13 @@ static void cpu_record_print(struct vty *vty, uint8_t filter) vty_out(vty, " CPU_Warn Wall_Warn Starv_Warn Type Thread\n"); - if (m->cpu_record->count) - hash_iterate( - m->cpu_record, - (void (*)(struct hash_bucket *, - void *))cpu_record_hash_print, - args); - else + if (cpu_records_count(m->cpu_records)) { + struct cpu_event_history *rec; + + frr_each (cpu_records, m->cpu_records, rec) + cpu_record_print_one(vty, filter, &tmp, + rec); + } else vty_out(vty, "No data to display yet.\n"); vty_out(vty, "\n"); @@ -248,35 +251,29 @@ static void cpu_record_print(struct vty *vty, uint8_t filter) vty_out_cpu_event_history(vty, &tmp); } -static void cpu_record_hash_clear(struct hash_bucket *bucket, void *args[]) -{ - uint8_t *filter = args[0]; - struct hash *cpu_record = args[1]; - - struct cpu_event_history *a = bucket->data; - - if (!(a->types & *filter)) - return; - - hash_release(cpu_record, bucket->data); -} - static void cpu_record_clear(uint8_t filter) { - uint8_t *tmp = &filter; struct event_loop *m; struct listnode *ln; frr_with_mutex (&masters_mtx) { for (ALL_LIST_ELEMENTS_RO(masters, ln, m)) { frr_with_mutex (&m->mtx) { - void *args[2] = {tmp, m->cpu_record}; + struct cpu_event_history *item; + struct cpu_records_head old[1]; + + cpu_records_init(old); + cpu_records_swap_all(old, m->cpu_records); - hash_iterate( - m->cpu_record, - (void (*)(struct hash_bucket *, - void *))cpu_record_hash_clear, - args); + while ((item = cpu_records_pop(old))) { + if (item->types & filter) + cpu_records_free(&item); + else + cpu_records_add(m->cpu_records, + item); + } + + cpu_records_fini(old); } } } @@ -565,10 +562,7 @@ struct event_loop *event_master_create(const char *name) snprintf(tmhashname, sizeof(tmhashname), "%s - threadmaster event hash", name); - rv->cpu_record = hash_create_size( - 8, (unsigned int (*)(const void *))cpu_record_hash_key, - (bool (*)(const void *, const void *))cpu_record_hash_cmp, - tmhashname); + cpu_records_init(rv->cpu_records); event_list_init(&rv->event); event_list_init(&rv->ready); @@ -686,6 +680,7 @@ void event_master_free_unused(struct event_loop *m) /* Stop thread scheduler. */ void event_master_free(struct event_loop *m) { + struct cpu_event_history *record; struct event *t; frr_with_mutex (&masters_mtx) { @@ -708,7 +703,9 @@ void event_master_free(struct event_loop *m) list_delete(&m->cancel_req); m->cancel_req = NULL; - hash_clean_and_free(&m->cpu_record, cpu_record_hash_free); + while ((record = cpu_records_pop(m->cpu_records))) + cpu_records_free(&record); + cpu_records_fini(m->cpu_records); XFREE(MTYPE_EVENT_MASTER, m->name); XFREE(MTYPE_EVENT_MASTER, m->handler.pfds); @@ -781,7 +778,6 @@ static struct event *thread_get(struct event_loop *m, uint8_t type, const struct xref_eventsched *xref) { struct event *thread = event_list_pop(&m->unuse); - struct cpu_event_history tmp; if (!thread) { thread = XCALLOC(MTYPE_THREAD, sizeof(struct event)); @@ -809,13 +805,9 @@ static struct event *thread_get(struct event_loop *m, uint8_t type, * hash_get lookups. */ if ((thread->xref && thread->xref->funcname != xref->funcname) - || thread->func != func) { - tmp.func = func; - tmp.funcname = xref->funcname; - thread->hist = - hash_get(m->cpu_record, &tmp, - (void *(*)(void *))cpu_record_hash_alloc); - } + || thread->func != func) + thread->hist = cpu_records_get(m, func, xref->funcname); + thread->hist->total_active++; thread->func = func; thread->xref = xref; diff --git a/lib/frrevent.h b/lib/frrevent.h index fe33ffd1f2..ab779d9088 100644 --- a/lib/frrevent.h +++ b/lib/frrevent.h @@ -65,6 +65,8 @@ struct xref_eventsched { uint32_t event_type; }; +PREDECL_HASH(cpu_records); + /* Master of the theads. */ struct event_loop { char *name; @@ -76,7 +78,7 @@ struct event_loop { struct list *cancel_req; bool canceled; pthread_cond_t cancel_cond; - struct hash *cpu_record; + struct cpu_records_head cpu_records[1]; int io_pipe[2]; int fd_limit; struct fd_handler handler; @@ -130,6 +132,8 @@ struct event { #endif struct cpu_event_history { + struct cpu_records_item item; + void (*func)(struct event *e); atomic_size_t total_cpu_warn; atomic_size_t total_wall_warn; diff --git a/lib/prefix.h b/lib/prefix.h index 7ca525e762..fc6e32dd54 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -377,9 +377,9 @@ static inline void ipv4_addr_copy(struct in_addr *dst, #endif /*s6_addr32*/ /* Prototypes. */ -extern int str2family(const char *); -extern int afi2family(afi_t); -extern afi_t family2afi(int); +extern int str2family(const char *string); +extern int afi2family(afi_t afi); +extern afi_t family2afi(int family); extern const char *family2str(int family); extern const char *safi2str(safi_t safi); extern const char *afi2str(afi_t afi); @@ -409,14 +409,15 @@ extern void prefix_free(struct prefix **p); extern void prefix_free_lists(void *arg); extern const char *prefix_family_str(union prefixconstptr pu); extern int prefix_blen(union prefixconstptr pu); -extern int str2prefix(const char *, struct prefix *); +extern int str2prefix(const char *string, struct prefix *prefix); #define PREFIX2STR_BUFFER PREFIX_STRLEN extern void prefix_mcast_inet4_dump(const char *onfail, struct in_addr addr, char *buf, int buf_size); extern const char *prefix_sg2str(const struct prefix_sg *sg, char *str); -extern const char *prefix2str(union prefixconstptr, char *, int); +extern const char *prefix2str(union prefixconstptr upfx, char *buffer, + int size); extern int evpn_type5_prefix_match(const struct prefix *evpn_pfx, const struct prefix *match_pfx); extern int prefix_match(union prefixconstptr unet, union prefixconstptr upfx); @@ -437,36 +438,37 @@ extern bool evpn_addr_same(const struct evpn_addr *e1, const struct evpn_addr *e #define prefix_copy(a, b) ({ memset(a, 0, sizeof(*a)); prefix_copy(a, b); }) #endif -extern struct prefix *sockunion2hostprefix(const union sockunion *, +extern struct prefix *sockunion2hostprefix(const union sockunion *su, struct prefix *p); -extern void prefix2sockunion(const struct prefix *, union sockunion *); +extern void prefix2sockunion(const struct prefix *p, union sockunion *su); -extern int str2prefix_eth(const char *, struct prefix_eth *); +extern int str2prefix_eth(const char *string, struct prefix_eth *p); extern struct prefix_ipv4 *prefix_ipv4_new(void); extern void prefix_ipv4_free(struct prefix_ipv4 **p); -extern int str2prefix_ipv4(const char *, struct prefix_ipv4 *); -extern void apply_mask_ipv4(struct prefix_ipv4 *); +extern int str2prefix_ipv4(const char *string, struct prefix_ipv4 *p); +extern void apply_mask_ipv4(struct prefix_ipv4 *p); -extern int prefix_ipv4_any(const struct prefix_ipv4 *); -extern void apply_classful_mask_ipv4(struct prefix_ipv4 *); +extern int prefix_ipv4_any(const struct prefix_ipv4 *p); +extern void apply_classful_mask_ipv4(struct prefix_ipv4 *p); -extern uint8_t ip_masklen(struct in_addr); -extern void masklen2ip(const int, struct in_addr *); +extern uint8_t ip_masklen(struct in_addr addr); +extern void masklen2ip(const int length, struct in_addr *addr); /* given the address of a host on a network and the network mask length, * calculate the broadcast address for that network; * special treatment for /31 according to RFC3021 section 3.3 */ extern in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen); -extern int netmask_str2prefix_str(const char *, const char *, char *, size_t); +extern int netmask_str2prefix_str(const char *net_str, const char *mask_str, + char *prefix_str, size_t prefix_str_len); extern struct prefix_ipv6 *prefix_ipv6_new(void); extern void prefix_ipv6_free(struct prefix_ipv6 **p); -extern int str2prefix_ipv6(const char *, struct prefix_ipv6 *); -extern void apply_mask_ipv6(struct prefix_ipv6 *); +extern int str2prefix_ipv6(const char *str, struct prefix_ipv6 *p); +extern void apply_mask_ipv6(struct prefix_ipv6 *p); -extern int ip6_masklen(struct in6_addr); -extern void masklen2ip6(const int, struct in6_addr *); +extern int ip6_masklen(struct in6_addr netmask); +extern void masklen2ip6(const int masklen, struct in6_addr *netmask); extern int is_zero_mac(const struct ethaddr *mac); extern bool is_mcast_mac(const struct ethaddr *mac); diff --git a/lib/srv6.h b/lib/srv6.h index 0d3ee7d2ff..7c8c6b4a65 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -24,6 +24,16 @@ extern "C" { #define sid2str(sid, str, size) \ inet_ntop(AF_INET6, sid, str, size) +/* SRv6 flavors manipulation macros */ +#define CHECK_SRV6_FLV_OP(OPS,OP) ((OPS) & (1 << OP)) +#define SET_SRV6_FLV_OP(OPS,OP) (OPS) |= (1 << OP) +#define UNSET_SRV6_FLV_OP(OPS,OP) (OPS) &= ~(1 << OP) +#define RESET_SRV6_FLV_OP(OPS) (OPS) = 0 + +/* SRv6 Flavors default values */ +#define ZEBRA_DEFAULT_SEG6_LOCAL_FLV_LCBLOCK_LEN 32 +#define ZEBRA_DEFAULT_SEG6_LOCAL_FLV_LCNODE_FN_LEN 16 + enum seg6_mode_t { INLINE, ENCAP, @@ -50,15 +60,40 @@ enum seg6local_action_t { ZEBRA_SEG6_LOCAL_ACTION_END_DT46 = 16, }; +/* Flavor operations for SRv6 End* Behaviors */ +enum seg6local_flavor_op { + ZEBRA_SEG6_LOCAL_FLV_OP_UNSPEC = 0, + /* PSP Flavor as per RFC 8986 section #4.16.1 */ + ZEBRA_SEG6_LOCAL_FLV_OP_PSP = 1, + /* USP Flavor as per RFC 8986 section #4.16.2 */ + ZEBRA_SEG6_LOCAL_FLV_OP_USP = 2, + /* USD Flavor as per RFC 8986 section #4.16.3 */ + ZEBRA_SEG6_LOCAL_FLV_OP_USD = 3, + /* NEXT-C-SID Flavor as per draft-ietf-spring-srv6-srh-compression-03 + section 4.1 */ + ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID = 4, +}; + struct seg6_segs { size_t num_segs; struct in6_addr segs[256]; }; +struct seg6local_flavors_info { + /* Flavor operations */ + uint32_t flv_ops; + + /* Locator-Block length, expressed in bits */ + uint8_t lcblock_len; + /* Locator-Node Function length, expressed in bits */ + uint8_t lcnode_func_len; +}; + struct seg6local_context { struct in_addr nh4; struct in6_addr nh6; uint32_t table; + struct seg6local_flavors_info flv; }; struct srv6_locator { @@ -115,14 +150,18 @@ struct srv6_locator_chunk { * https://www.iana.org/assignments/segment-routing/segment-routing.xhtml */ enum srv6_endpoint_behavior_codepoint { - SRV6_ENDPOINT_BEHAVIOR_RESERVED = 0x0000, - SRV6_ENDPOINT_BEHAVIOR_END_DT6 = 0x0012, - SRV6_ENDPOINT_BEHAVIOR_END_DT4 = 0x0013, - SRV6_ENDPOINT_BEHAVIOR_END_DT46 = 0x0014, - SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID = 0x003E, - SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID = 0x003F, - SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID = 0x0040, - SRV6_ENDPOINT_BEHAVIOR_OPAQUE = 0xFFFF, + SRV6_ENDPOINT_BEHAVIOR_RESERVED = 0x0000, + SRV6_ENDPOINT_BEHAVIOR_END = 0x0001, + SRV6_ENDPOINT_BEHAVIOR_END_X = 0x0005, + SRV6_ENDPOINT_BEHAVIOR_END_DT6 = 0x0012, + SRV6_ENDPOINT_BEHAVIOR_END_DT4 = 0x0013, + SRV6_ENDPOINT_BEHAVIOR_END_DT46 = 0x0014, + SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID = 0x002B, + SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID = 0x002C, + SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID = 0x003E, + SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID = 0x003F, + SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID = 0x0040, + SRV6_ENDPOINT_BEHAVIOR_OPAQUE = 0xFFFF, }; struct nexthop_srv6 { |
