/* * BIRD Internet Routing Daemon -- MPLS Structures * * (c) 2022 Ondrej Zajicek * (c) 2022 CZ.NIC z.s.p.o. * * Can be freely distributed and used under the terms of the GNU GPL. */ #ifndef _BIRD_MPLS_INTERNAL_H_ #define _BIRD_MPLS_INTERNAL_H_ #include "nest/bird.h" #include "lib/bitmap.h" #include "lib/hash.h" #include "nest/route.h" #include "nest/protocol.h" #include "nest/mpls.h" #include "lib/tlists.h" #define MPLS_DOMAIN_PUBLIC \ node n; /* Node in global list of MPLS domains (mpls_domains) */ \ const char *name; \ DOMAIN(attrs) lock; \ struct mpls_domain { MPLS_DOMAIN_PUBLIC; struct mpls_domain **locked_at; struct mpls_domain_config *cf; /* Our config */ pool *pool; /* Pool for the domain and associated objects */ struct lmap labels; /* Bitmap of allocated labels */ uint label_count; /* Number of allocated labels */ uint use_count; /* Reference counter */ struct config *removed; /* Deconfigured, waiting for zero use_count, while keeping config obstacle */ struct mpls_range *static_range; /* Direct static range pointer */ list ranges; /* List of label ranges (struct mpls_range) */ event range_cleanup; /* Event for asynchronous cleanup of removed ranges */ }; struct mpls_domain_pub { union { struct { MPLS_DOMAIN_PUBLIC; }; struct mpls_domain priv; }; }; #define mpls_domain_private mpls_domain #define MPLS_DOMAIN_LOCK(_obj, _pobj) LOBJ_LOCK(_obj, _pobj, mpls_domain, attrs) #define MPLS_DOMAIN_LOCKED(_obj, _pobj) LOBJ_LOCKED(_obj, _pobj, mpls_domain, attrs) LOBJ_UNLOCK_CLEANUP(mpls_domain, attrs); #define MPLS_DOMAIN_PRIV(_obj) LOBJ_PRIV(_obj, attrs) #define MPLS_DOMAIN_PUB(_pobj) SKIP_BACK(struct mpls_domain_pub, priv, (_pobj)) #define MPLS_RANGE_PUBLIC \ node n; /* Node in mpls_domain.ranges */ \ DOMAIN(attrs) lock; /* Shared with the domain */ \ struct mpls_range { MPLS_RANGE_PUBLIC; struct mpls_range **locked_at; struct mpls_range_config *cf; /* Our config */ const char *name; struct mpls_domain *domain; list handles; /* List of label handles (struct mpls_handle) */ uint lo, hi; /* Label range interval */ uint label_count; /* Number of allocated labels */ uint use_count; /* Reference counter */ u8 removed; /* Deconfigured, waiting for zero use_count */ }; struct mpls_range_pub { union { struct { MPLS_RANGE_PUBLIC; }; struct mpls_range priv; }; }; #define mpls_range_private mpls_range #define MPLS_RANGE_LOCK(_obj, _pobj) LOBJ_LOCK(_obj, _pobj, mpls_range, attrs) #define MPLS_RANGE_LOCKED(_obj, _pobj) LOBJ_LOCKED(_obj, _pobj, mpls_range, attrs) LOBJ_UNLOCK_CLEANUP(mpls_range, attrs); #define MPLS_RANGE_PRIV(_obj) LOBJ_PRIV(_obj, attrs) #define MPLS_RANGE_PUB(_pobj) SKIP_BACK(struct mpls_range_pub, priv, (_pobj)) #define MPLS_HANDLE_PUBLIC \ node n; /* Node in mpls_domain.handles */ \ const char *name; /* Shared with the range */ \ DOMAIN(attrs) lock; /* Shared with the domain */ \ struct mpls_handle { MPLS_HANDLE_PUBLIC; struct mpls_handle **locked_at; struct mpls_range *range; /* Associated range, keeping reference */ uint label_count; /* Number of allocated labels */ }; struct mpls_handle_pub { union { struct { MPLS_HANDLE_PUBLIC; }; struct mpls_handle priv; }; }; #define mpls_handle_private mpls_handle #define MPLS_HANDLE_LOCK(_obj, _pobj) LOBJ_LOCK(_obj, _pobj, mpls_handle, attrs) #define MPLS_HANDLE_LOCKED(_obj, _pobj) LOBJ_LOCKED(_obj, _pobj, mpls_handle, attrs) LOBJ_UNLOCK_CLEANUP(mpls_handle, attrs); #define MPLS_HANDLE_PRIV(_obj) LOBJ_PRIV(_obj, attrs) #define MPLS_HANDLE_PUB(_pobj) SKIP_BACK(struct mpls_handle_pub, priv, (_pobj)) uint mpls_new_label(struct mpls_handle *h, uint n); void mpls_free_label(struct mpls_handle *h, uint n); void mpls_move_label(struct mpls_handle *fh, struct mpls_handle *th, uint n); void mpls_lock_domain(struct mpls_domain *m); void mpls_unlock_domain(struct mpls_domain *m); void mpls_lock_range(struct mpls_range *m); void mpls_unlock_range(struct mpls_range *m); void mpls_revive_fec(struct mpls_fec *); #endif