diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-09 13:16:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-09 13:16:35 +0000 |
commit | e2bbf175a2184bd76f6c54ccf8456babeb1a46fc (patch) | |
tree | f0b76550d6e6f500ada964a3a4ee933a45e5a6f1 /zebra/zebra_router.h | |
parent | Initial commit. (diff) | |
download | frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.tar.xz frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.zip |
Adding upstream version 9.1.upstream/9.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'zebra/zebra_router.h')
-rw-r--r-- | zebra/zebra_router.h | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h new file mode 100644 index 0000000..bd86cfb --- /dev/null +++ b/zebra/zebra_router.h @@ -0,0 +1,326 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Zebra Router header. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + */ +#ifndef __ZEBRA_ROUTER_H__ +#define __ZEBRA_ROUTER_H__ + +#include "lib/mlag.h" + +#include "zebra/zebra_ns.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This header file contains the idea of a router and as such + * owns data that is associated with a router from zebra's + * perspective. + */ + +struct zebra_router_table { + RB_ENTRY(zebra_router_table) zebra_router_table_entry; + + uint32_t tableid; + afi_t afi; + safi_t safi; + ns_id_t ns_id; + + struct route_table *table; +}; +RB_HEAD(zebra_router_table_head, zebra_router_table); +RB_PROTOTYPE(zebra_router_table_head, zebra_router_table, + zebra_router_table_entry, zebra_router_table_entry_compare) + +/* RPF lookup behaviour */ +enum multicast_mode { + MCAST_NO_CONFIG = 0, /* MIX_MRIB_FIRST, but no show in config write */ + MCAST_MRIB_ONLY, /* MRIB only */ + MCAST_URIB_ONLY, /* URIB only */ + MCAST_MIX_MRIB_FIRST, /* MRIB, if nothing at all then URIB */ + MCAST_MIX_DISTANCE, /* MRIB & URIB, lower distance wins */ + MCAST_MIX_PFXLEN, /* MRIB & URIB, longer prefix wins */ + /* on equal value, MRIB wins for last 2 */ +}; + +/* An interface can be error-disabled if a protocol (such as EVPN or + * VRRP) detects a problem with keeping it operationally-up. + * If any of the protodown bits are set protodown-on is programmed + * in the dataplane. This results in a carrier/L1 down on the + * physical device. + */ +enum protodown_reasons { + /* A process outside of FRR's control protodowned the interface */ + ZEBRA_PROTODOWN_EXTERNAL = (1 << 0), + /* On startup local ESs are held down for some time to + * allow the underlay to converge and EVPN routes to + * get learnt + */ + ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY = (1 << 1), + /* If all the uplinks are down the switch has lost access + * to the VxLAN overlay and must shut down the access + * ports to allow servers to re-direct their traffic to + * other switches on the Ethernet Segment + */ + ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN = (1 << 2), + ZEBRA_PROTODOWN_EVPN_ALL = (ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN | + ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY), + ZEBRA_PROTODOWN_VRRP = (1 << 3), + /* This reason used exclusively for testing */ + ZEBRA_PROTODOWN_SHARP = (1 << 4), + /* Just used to clear our fields on shutdown, externel not included */ + ZEBRA_PROTODOWN_ALL = (ZEBRA_PROTODOWN_EVPN_ALL | ZEBRA_PROTODOWN_VRRP | + ZEBRA_PROTODOWN_SHARP) +}; +#define ZEBRA_PROTODOWN_RC_STR_LEN 80 + +struct zebra_mlag_info { + /* Role this zebra router is playing */ + enum mlag_role role; + + /* The peerlink being used for mlag */ + char *peerlink; + ifindex_t peerlink_ifindex; + + /* The system mac being used */ + struct ethaddr mac; + /* + * Zebra will open the communication channel with MLAGD only if any + * clients are interested and it is controlled dynamically based on + * client registers & un-registers. + */ + uint32_t clients_interested_cnt; + + /* coomunication channel with MLAGD is established */ + bool connected; + + /* connection retry timer is running */ + bool timer_running; + + /* Holds the client data(unencoded) that need to be pushed to MCLAGD*/ + struct stream_fifo *mlag_fifo; + + /* + * A new Kernel thread will be created to post the data to MCLAGD. + * where as, read will be performed from the zebra main thread, because + * read involves accessing client registartion data structures. + */ + struct frr_pthread *zebra_pth_mlag; + + /* MLAG Thread context 'master' */ + struct event_loop *th_master; + + /* + * Event for Initial MLAG Connection setup & Data Read + * Read can be performed only after successful connection establishment, + * so no issues. + * + */ + struct event *t_read; + /* Event for MLAG write */ + struct event *t_write; +}; + +struct zebra_router { + atomic_bool in_shutdown; + + /* Thread master */ + struct event_loop *master; + + /* Lists of clients who have connected to us */ + struct list *client_list; + + /* List of clients in GR */ + struct list *stale_client_list; + + struct zebra_router_table_head tables; + + /* L3-VNI hash table (for EVPN). Only in default instance */ + struct hash *l3vni_table; + + /* Tables and other global info maintained for EVPN multihoming */ + struct zebra_evpn_mh_info *mh_info; + + struct zebra_neigh_info *neigh_info; + + /* EVPN MH broadcast domains indexed by the VID */ + struct hash *evpn_vlan_table; + + struct hash *rules_hash; + + struct hash *ipset_hash; + + struct hash *ipset_entry_hash; + + struct hash *iptable_hash; + + struct hash *qdisc_hash; + struct hash *class_hash; + struct hash *filter_hash; + + /* A sequence number used for tracking routes */ + _Atomic uint32_t sequence_num; + + /* rib work queue */ +#define ZEBRA_RIB_PROCESS_HOLD_TIME 10 +#define ZEBRA_RIB_PROCESS_RETRY_TIME 1 + struct work_queue *ribq; + + /* Meta Queue Information */ + struct meta_queue *mq; + + /* LSP work queue */ + struct work_queue *lsp_process_q; + +#define ZEBRA_ZAPI_PACKETS_TO_PROCESS 1000 + _Atomic uint32_t packets_to_process; + + /* Mlag information for the router */ + struct zebra_mlag_info mlag_info; + + /* + * The EVPN instance, if any + */ + struct zebra_vrf *evpn_vrf; + + uint32_t multipath_num; + + /* RPF Lookup behavior */ + enum multicast_mode ipv4_multicast_mode; + + /* + * Time for when we sweep the rib from old routes + */ + time_t startup_time; + struct event *sweeper; + + /* + * The hash of nexthop groups associated with this router + */ + struct hash *nhgs; + struct hash *nhgs_id; + + /* + * Does the underlying system provide an asic offload + */ + bool asic_offloaded; + bool notify_on_ack; + bool v6_with_v4_nexthop; + + /* + * If the asic is notifying us about successful nexthop + * allocation/control. Some developers have made their + * asic take control of how many nexthops/ecmp they can + * have and will report what is successfull or not + */ + bool asic_notification_nexthop_control; + + bool supports_nhgs; + + bool all_mc_forwardingv4, default_mc_forwardingv4; + bool all_mc_forwardingv6, default_mc_forwardingv6; + bool all_linkdownv4, default_linkdownv4; + bool all_linkdownv6, default_linkdownv6; + +#define ZEBRA_DEFAULT_NHG_KEEP_TIMER 180 + uint32_t nhg_keep; + + /* Should we allow non FRR processes to delete our routes */ + bool allow_delete; + + uint8_t protodown_r_bit; +}; + +#define GRACEFUL_RESTART_TIME 60 + +extern struct zebra_router zrouter; +extern uint32_t rcvbufsize; + +extern void zebra_router_init(bool asic_offload, bool notify_on_ack, + bool v6_with_v4_nexthop); +extern void zebra_router_cleanup(void); +extern void zebra_router_terminate(void); + +extern struct zebra_router_table *zebra_router_find_zrt(struct zebra_vrf *zvrf, + uint32_t tableid, + afi_t afi, safi_t safi); +extern struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf, + uint32_t tableid, afi_t afi, + safi_t safi); +extern struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf, + uint32_t tableid, afi_t afi, + safi_t safi); +extern void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid, + afi_t afi, safi_t safi); + +extern int zebra_router_config_write(struct vty *vty); + +extern void zebra_router_sweep_route(void); +extern void zebra_router_sweep_nhgs(void); + +extern void zebra_router_show_table_summary(struct vty *vty); + +extern uint32_t zebra_router_get_next_sequence(void); + +static inline vrf_id_t zebra_vrf_get_evpn_id(void) +{ + return zrouter.evpn_vrf ? zvrf_id(zrouter.evpn_vrf) : VRF_DEFAULT; +} +static inline struct zebra_vrf *zebra_vrf_get_evpn(void) +{ + return zrouter.evpn_vrf ? zrouter.evpn_vrf + : zebra_vrf_lookup_by_id(VRF_DEFAULT); +} + +extern void multicast_mode_ipv4_set(enum multicast_mode mode); + +extern enum multicast_mode multicast_mode_ipv4_get(void); + +extern bool zebra_router_notify_on_ack(void); + +static inline void zebra_router_set_supports_nhgs(bool support) +{ + zrouter.supports_nhgs = support; +} + +static inline bool zebra_router_in_shutdown(void) +{ + return atomic_load_explicit(&zrouter.in_shutdown, memory_order_relaxed); +} + +#define FRR_PROTODOWN_REASON_DEFAULT_BIT 7 +/* Protodown bit setter/getter + * + * Allow users to change the bit if it conflicts with another + * on their system. + */ +static inline void if_netlink_set_frr_protodown_r_bit(uint8_t bit) +{ + zrouter.protodown_r_bit = bit; +} + +static inline void if_netlink_unset_frr_protodown_r_bit(void) +{ + zrouter.protodown_r_bit = FRR_PROTODOWN_REASON_DEFAULT_BIT; +} + +static inline bool if_netlink_frr_protodown_r_bit_is_set(void) +{ + return (zrouter.protodown_r_bit != FRR_PROTODOWN_REASON_DEFAULT_BIT); +} + +static inline uint8_t if_netlink_get_frr_protodown_r_bit(void) +{ + return zrouter.protodown_r_bit; +} + +/* zebra_northbound.c */ +extern const struct frr_yang_module_info frr_zebra_info; + +#ifdef __cplusplus +} +#endif + +#endif |