LCOV - code coverage report
Current view: top level - plugins/wireguard - wireguard_peer.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 19 24 79.2 %
Date: 2023-07-05 22:20:52 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2020 Doc.ai and/or its affiliates.
       3             :  * Copyright (c) 2020 Cisco and/or its affiliates.
       4             :  * Licensed under the Apache License, Version 2.0 (the "License");
       5             :  * you may not use this file except in compliance with the License.
       6             :  * You may obtain a copy of the License at:
       7             :  *
       8             :  *     http://www.apache.org/licenses/LICENSE-2.0
       9             :  *
      10             :  * Unless required by applicable law or agreed to in writing, software
      11             :  * distributed under the License is distributed on an "AS IS" BASIS,
      12             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13             :  * See the License for the specific language governing permissions and
      14             :  * limitations under the License.
      15             :  */
      16             : 
      17             : #ifndef __included_wg_peer_h__
      18             : #define __included_wg_peer_h__
      19             : 
      20             : #include <vlibapi/api_helper_macros.h>
      21             : 
      22             : #include <vnet/ip/ip.h>
      23             : 
      24             : #include <wireguard/wireguard_cookie.h>
      25             : #include <wireguard/wireguard_timer.h>
      26             : #include <wireguard/wireguard_key.h>
      27             : #include <wireguard/wireguard_messages.h>
      28             : #include <wireguard/wireguard_if.h>
      29             : 
      30             : typedef struct ip4_udp_header_t_
      31             : {
      32             :   ip4_header_t ip4;
      33             :   udp_header_t udp;
      34             : } __clib_packed ip4_udp_header_t;
      35             : 
      36             : typedef struct ip4_udp_wg_header_t_
      37             : {
      38             :   ip4_header_t ip4;
      39             :   udp_header_t udp;
      40             :   message_data_t wg;
      41             : } __clib_packed ip4_udp_wg_header_t;
      42             : 
      43             : typedef struct ip6_udp_header_t_
      44             : {
      45             :   ip6_header_t ip6;
      46             :   udp_header_t udp;
      47             : } __clib_packed ip6_udp_header_t;
      48             : 
      49             : typedef struct ip6_udp_wg_header_t_
      50             : {
      51             :   ip6_header_t ip6;
      52             :   udp_header_t udp;
      53             :   message_data_t wg;
      54             : } __clib_packed ip6_udp_wg_header_t;
      55             : 
      56             : u8 *format_ip4_udp_header (u8 * s, va_list * va);
      57             : u8 *format_ip6_udp_header (u8 *s, va_list *va);
      58             : 
      59             : typedef struct wg_peer_endpoint_t_
      60             : {
      61             :   ip46_address_t addr;
      62             :   u16 port;
      63             : } wg_peer_endpoint_t;
      64             : 
      65             : typedef enum
      66             : {
      67             :   WG_PEER_STATUS_DEAD = 0x1,
      68             :   WG_PEER_ESTABLISHED = 0x2,
      69             : } wg_peer_flags;
      70             : 
      71             : typedef struct wg_peer
      72             : {
      73             :   noise_remote_t remote;
      74             :   cookie_maker_t cookie_maker;
      75             : 
      76             :   u32 input_thread_index;
      77             :   u32 output_thread_index;
      78             : 
      79             :   /* Peer addresses */
      80             :   wg_peer_endpoint_t dst;
      81             :   wg_peer_endpoint_t src;
      82             :   u32 table_id;
      83             :   adj_index_t *adj_indices;
      84             : 
      85             :   /* rewrite built from address information */
      86             :   u8 *rewrite;
      87             : 
      88             :   /* Vector of allowed-ips */
      89             :   fib_prefix_t *allowed_ips;
      90             : 
      91             :   /* The WG interface this peer is attached to */
      92             :   u32 wg_sw_if_index;
      93             : 
      94             :   /* API client registered for events */
      95             :   vpe_client_registration_t *api_clients;
      96             :   uword *api_client_by_client_index;
      97             :   wg_peer_flags flags;
      98             : 
      99             :   /* Timers */
     100             :   tw_timer_wheel_16t_2w_512sl_t *timer_wheel;
     101             :   u32 timers[WG_N_TIMERS];
     102             :   u8 timers_dispatched[WG_N_TIMERS];
     103             :   u32 timer_handshake_attempts;
     104             :   u16 persistent_keepalive_interval;
     105             : 
     106             :   /* Timestamps */
     107             :   f64 last_sent_handshake;
     108             :   f64 last_sent_packet;
     109             :   f64 last_received_packet;
     110             :   f64 session_derived;
     111             :   f64 rehandshake_started;
     112             : 
     113             :   /* Variable intervals */
     114             :   u32 new_handshake_interval_tick;
     115             :   u32 rehandshake_interval_tick;
     116             : 
     117             :   bool timer_need_another_keepalive;
     118             : 
     119             :   /* Handshake is sent to main thread? */
     120             :   bool handshake_is_sent;
     121             : } wg_peer_t;
     122             : 
     123             : typedef struct wg_peer_table_bind_ctx_t_
     124             : {
     125             :   ip_address_family_t af;
     126             :   u32 new_fib_index;
     127             :   u32 old_fib_index;
     128             : } wg_peer_table_bind_ctx_t;
     129             : 
     130             : int wg_peer_add (u32 tun_sw_if_index,
     131             :                  const u8 public_key_64[NOISE_PUBLIC_KEY_LEN],
     132             :                  u32 table_id,
     133             :                  const ip46_address_t * endpoint,
     134             :                  const fib_prefix_t * allowed_ips,
     135             :                  u16 port, u16 persistent_keepalive, index_t * peer_index);
     136             : int wg_peer_remove (u32 peer_index);
     137             : 
     138             : typedef walk_rc_t (*wg_peer_walk_cb_t) (index_t peeri, void *arg);
     139             : index_t wg_peer_walk (wg_peer_walk_cb_t fn, void *data);
     140             : 
     141             : u8 *format_wg_peer (u8 * s, va_list * va);
     142             : 
     143             : walk_rc_t wg_peer_if_admin_state_change (index_t peeri, void *data);
     144             : walk_rc_t wg_peer_if_delete (index_t peeri, void *data);
     145             : walk_rc_t wg_peer_if_adj_change (index_t peeri, void *data);
     146             : adj_walk_rc_t wg_peer_adj_walk (adj_index_t ai, void *data);
     147             : 
     148             : void wg_api_peer_event (index_t peeri, wg_peer_flags flags);
     149             : void wg_peer_update_flags (index_t peeri, wg_peer_flags flag, bool add_del);
     150             : void wg_peer_update_endpoint (index_t peeri, const ip46_address_t *addr,
     151             :                               u16 port);
     152             : void wg_peer_update_endpoint_from_mt (index_t peeri,
     153             :                                       const ip46_address_t *addr, u16 port);
     154             : 
     155             : static inline bool
     156        3990 : wg_peer_is_dead (wg_peer_t *peer)
     157             : {
     158        3990 :   return peer && peer->flags & WG_PEER_STATUS_DEAD;
     159             : }
     160             : 
     161             : /*
     162             :  * Expoed for the data-plane
     163             :  */
     164             : extern index_t *wg_peer_by_adj_index;
     165             : extern wg_peer_t *wg_peer_pool;
     166             : 
     167             : static inline wg_peer_t *
     168        8930 : wg_peer_get (index_t peeri)
     169             : {
     170        8930 :   return (pool_elt_at_index (wg_peer_pool, peeri));
     171             : }
     172             : 
     173             : static inline index_t
     174         573 : wg_peer_get_by_adj_index (index_t ai)
     175             : {
     176         573 :   if (ai >= vec_len (wg_peer_by_adj_index))
     177           0 :     return INDEX_INVALID;
     178         573 :   return (wg_peer_by_adj_index[ai]);
     179             : }
     180             : 
     181             : /*
     182             :  * Makes choice for thread_id should be assigned.
     183             : */
     184             : static inline u32
     185          79 : wg_peer_assign_thread (u32 thread_id)
     186             : {
     187             :   return ((thread_id) ? thread_id
     188          79 :           : (vlib_num_workers ()?
     189           0 :              ((unix_time_now_nsec () % vlib_num_workers ()) +
     190             :               1) : thread_id));
     191             : }
     192             : 
     193             : static_always_inline bool
     194        4990 : fib_prefix_is_cover_addr_46 (const fib_prefix_t *p1, const ip46_address_t *ip)
     195             : {
     196        4990 :   switch (p1->fp_proto)
     197             :     {
     198        3924 :     case FIB_PROTOCOL_IP4:
     199        3924 :       return (ip4_destination_matches_route (&ip4_main, &p1->fp_addr.ip4,
     200        3924 :                                              &ip->ip4, p1->fp_len) != 0);
     201        1066 :     case FIB_PROTOCOL_IP6:
     202        1066 :       return (ip6_destination_matches_route (&ip6_main, &p1->fp_addr.ip6,
     203        1066 :                                              &ip->ip6, p1->fp_len) != 0);
     204           0 :     case FIB_PROTOCOL_MPLS:
     205           0 :       break;
     206             :     }
     207           0 :   return (false);
     208             : }
     209             : 
     210             : static inline bool
     211         317 : wg_peer_can_send (wg_peer_t *peer)
     212             : {
     213         317 :   return peer && peer->rewrite;
     214             : }
     215             : 
     216             : #endif // __included_wg_peer_h__
     217             : 
     218             : /*
     219             :  * fd.io coding-style-patch-verification: ON
     220             :  *
     221             :  * Local Variables:
     222             :  * eval: (c-set-style "gnu")
     223             :  * End:
     224             :  */

Generated by: LCOV version 1.14