LCOV - code coverage report
Current view: top level - vnet/bfd - bfd_main.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 21 22 95.5 %
Date: 2023-07-05 22:20:52 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2011-2016 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : /**
      16             :  * @file
      17             :  * @brief BFD global declarations
      18             :  */
      19             : #ifndef __included_bfd_main_h__
      20             : #define __included_bfd_main_h__
      21             : 
      22             : #include <vnet/vnet.h>
      23             : #include <vnet/bfd/bfd_protocol.h>
      24             : #include <vnet/bfd/bfd_udp.h>
      25             : #include <vlib/log.h>
      26             : #include <vppinfra/os.h>
      27             : #include <vppinfra/tw_timer_1t_3w_1024sl_ov.h>
      28             : 
      29             : #define foreach_bfd_mode(F) \
      30             :   F (asynchronous)          \
      31             :   F (demand)
      32             : 
      33             : typedef enum
      34             : {
      35             : #define F(x) BFD_MODE_##x,
      36             :   foreach_bfd_mode (F)
      37             : #undef F
      38             : } bfd_mode_e;
      39             : 
      40             : typedef struct
      41             : {
      42             :   /** global configuration key ID */
      43             :   u32 conf_key_id;
      44             : 
      45             :   /** keeps track of how many sessions reference this key */
      46             :   u32 use_count;
      47             : 
      48             :   /**
      49             :    * key data directly usable for bfd purposes - already padded with zeroes
      50             :    * (so we don't need the actual length)
      51             :    */
      52             :   u8 key[20];
      53             : 
      54             :   /** authentication type for this key */
      55             :   bfd_auth_type_e auth_type;
      56             : } bfd_auth_key_t;
      57             : 
      58             : #define foreach_bfd_poll_state(F) \
      59             :   F (NOT_NEEDED)                  \
      60             :   F (NEEDED)                      \
      61             :   F (IN_PROGRESS)                 \
      62             :   F (IN_PROGRESS_AND_QUEUED)
      63             : 
      64             : typedef enum
      65             : {
      66             : #define F(x) BFD_POLL_##x,
      67             :   foreach_bfd_poll_state (F)
      68             : #undef F
      69             : } bfd_poll_state_e;
      70             : 
      71             : /**
      72             :  * hop types
      73             :  */
      74             : #define foreach_bfd_hop(F)                     \
      75             :   F (SINGLE, "single")                         \
      76             :   F (MULTI,  "multi")                          \
      77             : 
      78             : typedef enum
      79             : {
      80             : #define F(sym, str) BFD_HOP_TYPE_##sym,
      81             :   foreach_bfd_hop (F)
      82             : #undef F
      83             : } bfd_hop_type_e;
      84             : 
      85             : typedef struct bfd_session_s
      86             : {
      87             :   /** index in bfd_main.sessions pool */
      88             :   u32 bs_idx;
      89             : 
      90             :   /** session state */
      91             :   bfd_state_e local_state;
      92             : 
      93             :   /** remote session state */
      94             :   bfd_state_e remote_state;
      95             : 
      96             :   /** BFD hop type */
      97             :   bfd_hop_type_e hop_type;
      98             : 
      99             :   /** local diagnostics */
     100             :   bfd_diag_code_e local_diag;
     101             : 
     102             :   /** remote diagnostics */
     103             :   bfd_diag_code_e remote_diag;
     104             : 
     105             :   /** local discriminator */
     106             :   u32 local_discr;
     107             : 
     108             :   /** remote discriminator */
     109             :   u32 remote_discr;
     110             : 
     111             :   /** configured desired min tx interval (microseconds) */
     112             :   u32 config_desired_min_tx_usec;
     113             : 
     114             :   /** configured desired min tx interval (nsec) */
     115             :   u64 config_desired_min_tx_nsec;
     116             : 
     117             :   /** effective desired min tx interval (nsec) */
     118             :   u64 effective_desired_min_tx_nsec;
     119             : 
     120             :   /** configured required min rx interval (microseconds) */
     121             :   u32 config_required_min_rx_usec;
     122             : 
     123             :   /** configured required min rx interval (nsec) */
     124             :   u64 config_required_min_rx_nsec;
     125             : 
     126             :   /** effective required min rx interval (nsec) */
     127             :   u64 effective_required_min_rx_nsec;
     128             : 
     129             :   /** remote min rx interval (microseconds) */
     130             :   u64 remote_min_rx_usec;
     131             : 
     132             :   /** remote min rx interval (nsec) */
     133             :   u64 remote_min_rx_nsec;
     134             : 
     135             :   /** remote min echo rx interval (microseconds) */
     136             :   u64 remote_min_echo_rx_usec;
     137             : 
     138             :   /** remote min echo rx interval (nsec) */
     139             :   u64 remote_min_echo_rx_nsec;
     140             : 
     141             :   /** remote desired min tx interval (nsec) */
     142             :   u64 remote_desired_min_tx_nsec;
     143             : 
     144             :   /** configured detect multiplier */
     145             :   u8 local_detect_mult;
     146             : 
     147             :   /** 1 if remote system sets demand mode, 0 otherwise */
     148             :   u8 remote_demand;
     149             : 
     150             :   /** remote detect multiplier */
     151             :   u8 remote_detect_mult;
     152             : 
     153             :   /** 1 is echo function is active, 0 otherwise */
     154             :   u8 echo;
     155             : 
     156             :   /** next event time in nsec for this session (0 if no event) */
     157             :   u64 event_time_nsec;
     158             : 
     159             :   /** timing wheel internal id used to manipulate timer (if set) */
     160             :   u32 tw_id;
     161             : 
     162             :   /** transmit interval */
     163             :   u64 transmit_interval_nsec;
     164             : 
     165             :   /** next time at which to transmit a packet */
     166             :   u64 tx_timeout_nsec;
     167             : 
     168             :   /** timestamp of last packet transmitted */
     169             :   u64 last_tx_nsec;
     170             : 
     171             :   /** timestamp of last packet received */
     172             :   u64 last_rx_nsec;
     173             : 
     174             :   /** transmit interval for echo packets */
     175             :   u64 echo_transmit_interval_nsec;
     176             : 
     177             :   /** next time at which to transmit echo packet */
     178             :   u64 echo_tx_timeout_nsec;
     179             : 
     180             :   /** timestamp of last echo packet transmitted */
     181             :   u64 echo_last_tx_nsec;
     182             : 
     183             :   /** timestamp of last echo packet received */
     184             :   u64 echo_last_rx_nsec;
     185             : 
     186             :   /** secret used for calculating/checking checksum of echo packets */
     187             :   u32 echo_secret;
     188             : 
     189             :   /** detection time */
     190             :   u64 detection_time_nsec;
     191             : 
     192             :   /** state info regarding poll sequence */
     193             :   bfd_poll_state_e poll_state;
     194             : 
     195             :   /**
     196             :    * helper for delayed poll sequence - marks either start of running poll
     197             :    * sequence or timeout, after which we can start the next poll sequnce
     198             :    */
     199             :   u64 poll_state_start_or_timeout_nsec;
     200             : 
     201             :   /** authentication information */
     202             :   struct
     203             :   {
     204             :     /** current key in use */
     205             :     bfd_auth_key_t *curr_key;
     206             : 
     207             :     /**
     208             :      * set to next key to use if delayed switch is enabled - in that case
     209             :      * the key is switched when first incoming packet is signed with next_key
     210             :      */
     211             :     bfd_auth_key_t *next_key;
     212             : 
     213             :     /** sequence number incremented occasionally or always (if meticulous) */
     214             :     u32 local_seq_number;
     215             : 
     216             :     /** remote sequence number */
     217             :     u32 remote_seq_number;
     218             : 
     219             :     /** set to 1 if remote sequence number is known */
     220             :     u8 remote_seq_number_known;
     221             : 
     222             :     /** current key ID sent out in bfd packet */
     223             :     u8 curr_bfd_key_id;
     224             : 
     225             :     /** key ID to use when switched to next_key */
     226             :     u8 next_bfd_key_id;
     227             : 
     228             :     /**
     229             :      * set to 1 if delayed action is pending, which might be activation
     230             :      * of authentication, change of key or deactivation
     231             :      */
     232             :     u8 is_delayed;
     233             :   } auth;
     234             : 
     235             :   /** transport type for this session */
     236             :   bfd_transport_e transport;
     237             : 
     238             :   /** union of transport-specific data */
     239             :   union
     240             :   {
     241             :     bfd_udp_session_t udp;
     242             :   };
     243             : } bfd_session_t;
     244             : 
     245             : /**
     246             :  * listener events
     247             :  */
     248             : #define foreach_bfd_listen_event(F)            \
     249             :   F (CREATE, "sesion-created")                 \
     250             :   F (UPDATE, "session-updated")                \
     251             :   F (DELETE, "session-deleted")
     252             : 
     253             : typedef enum
     254             : {
     255             : #define F(sym, str) BFD_LISTEN_EVENT_##sym,
     256             :   foreach_bfd_listen_event (F)
     257             : #undef F
     258             : } bfd_listen_event_e;
     259             : 
     260             : /**
     261             :  * session notification call back function type
     262             :  */
     263             : typedef void (*bfd_notify_fn_t) (bfd_listen_event_e, const bfd_session_t *);
     264             : 
     265             : typedef struct
     266             : {
     267             :   /** lock to protect data structures */
     268             :   clib_spinlock_t lock;
     269             :   int lock_recursion_count;
     270             :   uword owner_thread_index;
     271             : 
     272             :   /** Number of event wakeup RPCs in flight. Should be 0 or 1 */
     273             :   int bfd_process_wakeup_events_in_flight;
     274             : 
     275             :   /** The timestamp of last wakeup event being sent */
     276             :   u64 bfd_process_wakeup_event_start_nsec;
     277             : 
     278             :   /** The time it took the last wakeup event to make it to handling */
     279             :   u64 bfd_process_wakeup_event_delay_nsec;
     280             : 
     281             :   /** When the bfd process is supposed to wake up next */
     282             :   u64 bfd_process_next_wakeup_nsec;
     283             : 
     284             :   /** pool of bfd sessions context data */
     285             :   bfd_session_t *sessions;
     286             : 
     287             :   /** timing wheel for scheduling timeouts */
     288             :     TWT (tw_timer_wheel) wheel;
     289             : 
     290             :   /** hashmap - bfd session by discriminator */
     291             :   u32 *session_by_disc;
     292             : 
     293             :   /** background process node index */
     294             :   u32 bfd_process_node_index;
     295             : 
     296             :   /** convenience variables */
     297             :   vlib_main_t *vlib_main;
     298             :   vnet_main_t *vnet_main;
     299             : 
     300             :   /** how many nanoseconds is one timing wheel tick */
     301             :   u64 nsec_per_tw_tick;
     302             : 
     303             :   /** default desired min tx in nsec */
     304             :   u64 default_desired_min_tx_nsec;
     305             : 
     306             :   /** minimum required min rx while echo function is active - nsec */
     307             :   u64 min_required_min_rx_while_echo_nsec;
     308             : 
     309             :   /** for generating random numbers */
     310             :   u32 random_seed;
     311             : 
     312             :   /** pool of authentication keys */
     313             :   bfd_auth_key_t *auth_keys;
     314             : 
     315             :   /** hashmap - index in pool auth_keys by conf_key_id */
     316             :   u32 *auth_key_by_conf_key_id;
     317             : 
     318             :   /** vector of callback notification functions */
     319             :   bfd_notify_fn_t *listeners;
     320             : 
     321             :   /** log class */
     322             :   vlib_log_class_t log_class;
     323             : 
     324             :   u16 msg_id_base;
     325             : 
     326             :   vlib_combined_counter_main_t rx_counter;
     327             :   vlib_combined_counter_main_t rx_echo_counter;
     328             :   vlib_combined_counter_main_t tx_counter;
     329             :   vlib_combined_counter_main_t tx_echo_counter;
     330             : } bfd_main_t;
     331             : 
     332             : extern bfd_main_t bfd_main;
     333             : 
     334             : /** Packet counters */
     335             : #define foreach_bfd_error(F)                                                  \
     336             :   F (NONE, "good bfd packets (processed)")                                    \
     337             :   F (BAD, "invalid bfd packets")                                              \
     338             :   F (DISABLED, "bfd packets received on disabled interfaces")                 \
     339             :   F (VERSION, "version")                                                      \
     340             :   F (LENGTH, "length")                                                        \
     341             :   F (DETECT_MULTI, "detect-multi")                                            \
     342             :   F (MULTI_POINT, "multi-point")                                              \
     343             :   F (MY_DISC, "my-disc")                                                      \
     344             :   F (YOUR_DISC, "your-disc")                                                  \
     345             :   F (ADMIN_DOWN, "session admin-down")
     346             : 
     347             : typedef enum
     348             : {
     349             : #define F(sym, str) BFD_ERROR_##sym,
     350             :   foreach_bfd_error (F)
     351             : #undef F
     352             :     BFD_N_ERROR,
     353             : } bfd_error_t;
     354             : 
     355             : /** bfd packet trace capture */
     356             : typedef struct
     357             : {
     358             :   u32 len;
     359             :   u8 data[400];
     360             : } bfd_input_trace_t;
     361             : 
     362             : typedef enum
     363             : {
     364             :   BFD_EVENT_RESCHEDULE = 1,
     365             :   BFD_EVENT_NEW_SESSION,
     366             :   BFD_EVENT_CONFIG_CHANGED,
     367             : } bfd_process_event_e;
     368             : 
     369             : /* *INDENT-OFF* */
     370             : /** echo packet structure */
     371             : typedef CLIB_PACKED (struct {
     372             :   /** local discriminator */
     373             :   u32 discriminator;
     374             :   /** expire time of this packet - nsec */
     375             :   u64 expire_time_nsec;
     376             :   /** checksum - based on discriminator, local secret and expire time */
     377             :   u64 checksum;
     378             : }) bfd_echo_pkt_t;
     379             : /* *INDENT-ON* */
     380             : 
     381             : static inline void
     382       19533 : bfd_lock (bfd_main_t * bm)
     383             : {
     384       19533 :   uword my_thread_index = __os_thread_index;
     385             : 
     386       19533 :   if (bm->owner_thread_index == my_thread_index
     387        4356 :       && bm->lock_recursion_count > 0)
     388             :     {
     389        4356 :       bm->lock_recursion_count++;
     390        4356 :       return;
     391             :     }
     392             : 
     393       15177 :   clib_spinlock_lock_if_init (&bm->lock);
     394       15177 :   bm->lock_recursion_count = 1;
     395       15177 :   bm->owner_thread_index = my_thread_index;
     396             : }
     397             : 
     398             : static inline void
     399       19533 : bfd_unlock (bfd_main_t * bm)
     400             : {
     401       19533 :   uword my_thread_index = __os_thread_index;
     402       19533 :   ASSERT (bm->owner_thread_index == my_thread_index);
     403             : 
     404       19533 :   if (bm->lock_recursion_count > 1)
     405             :     {
     406        4356 :       bm->lock_recursion_count--;
     407        4356 :       return;
     408             :     }
     409       15177 :   bm->lock_recursion_count = 0;
     410       15177 :   bm->owner_thread_index = ~0;
     411       15177 :   clib_spinlock_unlock_if_init (&bm->lock);
     412             : }
     413             : 
     414             : static inline void
     415        1802 : bfd_lock_check (bfd_main_t * bm)
     416             : {
     417        1802 :   if (PREDICT_FALSE (bm->lock_recursion_count < 1))
     418           0 :     clib_warning ("lock check failure");
     419        1802 : }
     420             : 
     421             : u8 *bfd_input_format_trace (u8 * s, va_list * args);
     422             : bfd_session_t *bfd_get_session (bfd_main_t * bm, bfd_transport_e t);
     423             : void bfd_put_session (bfd_main_t * bm, bfd_session_t * bs);
     424             : bfd_session_t *bfd_find_session_by_idx (bfd_main_t * bm, uword bs_idx);
     425             : bfd_session_t *bfd_find_session_by_disc (bfd_main_t * bm, u32 disc);
     426             : void bfd_session_start (bfd_main_t * bm, bfd_session_t * bs);
     427             : void bfd_session_stop (bfd_main_t *bm, bfd_session_t *bs);
     428             : bfd_error_t bfd_consume_pkt (vlib_main_t *vm, bfd_main_t *bm,
     429             :                              const bfd_pkt_t *bfd, u32 bs_idx);
     430             : bfd_session_t *bfd_consume_echo_pkt (vlib_main_t *vm, bfd_main_t *bm,
     431             :                                      vlib_buffer_t *b);
     432             : bfd_error_t bfd_verify_pkt_common (const bfd_pkt_t *pkt);
     433             : int bfd_verify_pkt_auth (vlib_main_t * vm, const bfd_pkt_t * pkt,
     434             :                          u16 pkt_size, bfd_session_t * bs);
     435             : void bfd_event (bfd_main_t * bm, bfd_session_t * bs);
     436             : void bfd_init_final_control_frame (vlib_main_t *vm, vlib_buffer_t *b,
     437             :                                    bfd_session_t *bs);
     438             : u8 *format_bfd_session (u8 * s, va_list * args);
     439             : u8 *format_bfd_session_brief (u8 * s, va_list * args);
     440             : u8 *format_bfd_auth_key (u8 * s, va_list * args);
     441             : void bfd_session_set_flags (vlib_main_t * vm, bfd_session_t * bs,
     442             :                             u8 admin_up_down);
     443             : unsigned bfd_auth_type_supported (bfd_auth_type_e auth_type);
     444             : vnet_api_error_t bfd_auth_activate (bfd_session_t * bs, u32 conf_key_id,
     445             :                                     u8 bfd_key_id, u8 is_delayed);
     446             : vnet_api_error_t bfd_auth_deactivate (bfd_session_t * bs, u8 is_delayed);
     447             : vnet_api_error_t bfd_session_set_params (bfd_main_t * bm, bfd_session_t * bs,
     448             :                                          u32 desired_min_tx_usec,
     449             :                                          u32 required_min_rx_usec,
     450             :                                          u8 detect_mult);
     451             : 
     452             : u32 bfd_nsec_to_usec (u64 nsec);
     453             : const char *bfd_poll_state_string (bfd_poll_state_e state);
     454             : 
     455             : #define USEC_PER_MS (1000LL)
     456             : #define MSEC_PER_SEC (1000LL)
     457             : #define NSEC_PER_USEC (1000LL)
     458             : #define USEC_PER_SEC (MSEC_PER_SEC * USEC_PER_MS)
     459             : #define NSEC_PER_SEC (NSEC_PER_USEC * USEC_PER_SEC)
     460             : #define SEC_PER_NSEC ((f64)1/NSEC_PER_SEC)
     461             : 
     462             : /** timing wheel tick-rate, 1ms should be good enough */
     463             : #define BFD_TW_TPS (MSEC_PER_SEC)
     464             : 
     465             : /** default, slow transmission interval for BFD packets, per spec at least 1s */
     466             : #define BFD_DEFAULT_DESIRED_MIN_TX_USEC USEC_PER_SEC
     467             : 
     468             : /**
     469             :  * minimum required min rx set locally when echo function is used, per spec
     470             :  * should be set to at least 1s
     471             :  */
     472             : #define BFD_REQUIRED_MIN_RX_USEC_WHILE_ECHO USEC_PER_SEC
     473             : 
     474             : /**
     475             :  * Register a callback function to receive session notifications.
     476             :  */
     477             : void bfd_register_listener (bfd_notify_fn_t fn);
     478             : 
     479             : typedef enum
     480             : {
     481             :   BFD_TX_IP4_ARP,
     482             :   BFD_TX_IP6_NDP,
     483             :   BFD_TX_IP4_REWRITE,
     484             :   BFD_TX_IP6_REWRITE,
     485             :   BFD_TX_IP4_MIDCHAIN,
     486             :   BFD_TX_IP6_MIDCHAIN,
     487             :   BFD_TX_N_NEXT,
     488             : } bfd_tx_next_t;
     489             : 
     490             : #endif /* __included_bfd_main_h__ */
     491             : 
     492             : /*
     493             :  * fd.io coding-style-patch-verification: ON
     494             :  *
     495             :  * Local Variables:
     496             :  * eval: (c-set-style "gnu")
     497             :  * End:
     498             :  */

Generated by: LCOV version 1.14