]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BMP: Refactor per-peer header arguments
authorOndrej Zajicek <santiago@crfreenet.org>
Sun, 1 Dec 2024 19:56:53 +0000 (20:56 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 2 Dec 2024 02:38:17 +0000 (03:38 +0100)
Put all arguments for per-peer header into one structure instead of
passing them around as a lump of arguments. Also simplify code for
peer flags.

proto/bmp/bmp.c

index 6dcf1562a027edeaffae321381f6ebe1bdf1e2ea..1af101ae41f23c3719fb74e71f61ef6aefb1b327 100644 (file)
@@ -103,32 +103,20 @@ enum bmp_peer_type {
   BMP_PEER_TYPE_LOCAL_INSTANCE = 2
 };
 
-#define BMP_PEER_HDR_FLAG_V_SHIFT 7
-enum bmp_peer_flag_v_t {
-  // The Peer address is an IPv4 address
-  BMP_PEER_HDR_FLAG_V_IP4 = (0 << BMP_PEER_HDR_FLAG_V_SHIFT),
-  // The Peer address is an IPv6 address
-  BMP_PEER_HDR_FLAG_V_IP6 = (1 << BMP_PEER_HDR_FLAG_V_SHIFT)
+#define BMP_PEER_FLAG_V_IPV6           (1 << 7)
+#define BMP_PEER_FLAG_L_POLICY         (1 << 6)
+#define BMP_PEER_FLAG_A_NO_AS4         (1 << 5)
+
+struct bmp_peer_hdr_info {
+  ip_addr address;
+  u32 as;
+  u32 id;
+  bool global;
+  bool policy;
+  bool no_as4;
+  btime timestamp;
 };
 
-#define BMP_PEER_HDR_FLAG_L_SHIFT 6
-enum bmp_peer_flag_l {
-  BMP_PEER_HDR_FLAG_L_PRE_POLICY_ADJ_RIB_IN = (0 << BMP_PEER_HDR_FLAG_L_SHIFT),
-  BMP_PEER_HDR_FLAG_L_POST_POLICY_ADJ_RIB_IN = (1 << BMP_PEER_HDR_FLAG_L_SHIFT)
-};
-
-#define BMP_PEER_HDR_FLAG_A_SHIFT 5
-enum bmp_peer_flag_a {
-  // The 4-byte AS_PATH format
-  BMP_PEER_HDR_FLAG_A_AS_PATH_4B = (0 << BMP_PEER_HDR_FLAG_A_SHIFT),
-  // The legacy 2-byte AS_PATH format
-  BMP_PEER_HDR_FLAG_A_AS_PATH_2B = (1 << BMP_PEER_HDR_FLAG_A_SHIFT)
-};
-
-#define BMP_PEER_HDR_FLAGS_INIT(flags) \
-  (flags) = 0
-#define BMP_PEER_HDR_FLAGS_SET(flags, bit_mask) \
-  (flags) |= (bit_mask)
 
 /* BMP Information TLV header [RFC 7854 - Section 4.4] */
 // Total size of Type and Length fields of Information TLV Header without
@@ -475,60 +463,44 @@ bmp_put_bgp_hdr(buffer *stream, const u8 msg_type, const u16 msg_length)
  * @ts_usec: the time in microseconds when the encapsulated routes were received
  */
 static void
-bmp_per_peer_hdr_serialize(buffer *stream, const bool is_global_instance_peer,
-  const bool is_post_policy, const bool is_as_path_4bytes,
-  const ip_addr peer_addr, const u32 peer_as, const u32 peer_bgp_id,
-  const u32 ts_sec, const u32 ts_usec)
+bmp_per_peer_hdr_serialize(buffer *stream, const struct bmp_peer_hdr_info *peer)
 {
-  // TODO: ATM we don't support BMP_PEER_TYPE_RD_INSTANCE
-  const enum bmp_peer_type peer_type = is_global_instance_peer
-                                      ? BMP_PEER_TYPE_GLOBAL_INSTANCE
-                                      : BMP_PEER_TYPE_LOCAL_INSTANCE;
-  const u8 peer_flag_v = ipa_is_ip4(peer_addr)
-                           ? BMP_PEER_HDR_FLAG_V_IP4
-                           : BMP_PEER_HDR_FLAG_V_IP6;
-  const u8 peer_flag_l = is_post_policy
-                           ? BMP_PEER_HDR_FLAG_L_POST_POLICY_ADJ_RIB_IN
-                           : BMP_PEER_HDR_FLAG_L_PRE_POLICY_ADJ_RIB_IN;
-  const u8 peer_flag_a = is_as_path_4bytes
-                           ? BMP_PEER_HDR_FLAG_A_AS_PATH_4B
-                           : BMP_PEER_HDR_FLAG_A_AS_PATH_2B;
-  u8 peer_flags;
-  BMP_PEER_HDR_FLAGS_INIT(peer_flags);
-  BMP_PEER_HDR_FLAGS_SET(peer_flags, peer_flag_v);
-  BMP_PEER_HDR_FLAGS_SET(peer_flags, peer_flag_l);
-  BMP_PEER_HDR_FLAGS_SET(peer_flags, peer_flag_a);
+  // TODO: ATM we do not support BMP_PEER_TYPE_RD_INSTANCE
+  u8 peer_type = peer->global ?
+    BMP_PEER_TYPE_GLOBAL_INSTANCE :
+    BMP_PEER_TYPE_LOCAL_INSTANCE;
+
+  u8 peer_flags =
+    (ipa_is_ip6(peer->address) ? BMP_PEER_FLAG_V_IPV6 : 0) |
+    (peer->policy ? BMP_PEER_FLAG_L_POLICY : 0) |
+    (peer->no_as4 ? BMP_PEER_FLAG_A_NO_AS4 : 0);
+
+  u32 ts_sec = peer->timestamp TO_S;
+  u32 ts_usec = peer->timestamp - (ts_sec S);
 
   bmp_put_u8(stream, peer_type);
   bmp_put_u8(stream, peer_flags);
-  // TODO: Provide appropriate peer Route Distinguisher if applicable
-  bmp_put_u64(stream, 0x00); // 0x00 - Not supported peer distinguisher
-  bmp_put_ipa(stream, peer_addr);
-  bmp_put_u32(stream, peer_as);
-  bmp_put_u32(stream, peer_bgp_id);
+  bmp_put_u64(stream, 0); // Not supported peer distinguisher
+  bmp_put_ipa(stream, peer->address);
+  bmp_put_u32(stream, peer->as);
+  bmp_put_u32(stream, peer->id);
   bmp_put_u32(stream, ts_sec);
   bmp_put_u32(stream, ts_usec);
 }
 
 /* [4.6] Route Monitoring */
 static byte *
-bmp_route_monitor_msg_serialize(struct bmp_proto *p, const bool is_peer_global,
-  const bool table_in_post_policy, const u32 peer_as, const u32 peer_bgp_id,
-  const bool as4_support, const ip_addr remote_addr, byte *update_msg,
-  const size_t update_msg_size, btime timestamp)
+bmp_route_monitor_msg_serialize(struct bmp_proto *p, const struct bmp_peer_hdr_info *peer,
+                               byte *update_msg, size_t update_msg_length)
 {
   ASSERT_DIE(update_msg < &p->msgbuf[sizeof p->msgbuf]);
 
   buffer stream;
   STACK_BUFFER_INIT(stream, BMP_PER_PEER_HDR_SIZE + BMP_COMMON_HDR_SIZE);
 
-  const size_t data_size = BMP_PER_PEER_HDR_SIZE + update_msg_size;
-  u32 ts_sec = timestamp TO_S;
-  u32 ts_usec = timestamp - (ts_sec S);
-
+  const size_t data_size = BMP_PER_PEER_HDR_SIZE + update_msg_length;
   bmp_common_hdr_serialize(&stream, BMP_ROUTE_MONITOR, data_size);
-  bmp_per_peer_hdr_serialize(&stream, is_peer_global, table_in_post_policy,
-    as4_support, remote_addr, peer_as, peer_bgp_id, ts_sec, ts_usec);
+  bmp_per_peer_hdr_serialize(&stream, peer);
 
   size_t hdr_sz = stream.pos - stream.start;
   ASSERT_DIE(update_msg >= &p->msgbuf[hdr_sz]);
@@ -539,11 +511,10 @@ bmp_route_monitor_msg_serialize(struct bmp_proto *p, const bool is_peer_global,
 }
 
 static void
-bmp_peer_up_notif_msg_serialize(buffer *stream, const bool is_peer_global,
-  const u32 peer_as, const u32 peer_bgp_id, const bool as4_support,
-  const ip_addr local_addr, const ip_addr remote_addr, const u16 local_port,
-  const u16 remote_port, const byte *sent_msg, const size_t sent_msg_length,
-  const byte *recv_msg, const size_t recv_msg_length)
+bmp_peer_up_notif_msg_serialize(buffer *stream, const struct bmp_peer_hdr_info *peer,
+                               const ip_addr local_addr, const u16 local_port, const u16 remote_port,
+                               const byte *sent_msg, const size_t sent_msg_length,
+                               const byte *recv_msg, const size_t recv_msg_length)
 {
   const size_t data_size =
     BMP_PER_PEER_HDR_SIZE + BMP_PEER_UP_NOTIF_MSG_FIX_SIZE +
@@ -551,9 +522,7 @@ bmp_peer_up_notif_msg_serialize(buffer *stream, const bool is_peer_global,
 
   bmp_buffer_need(stream, BMP_COMMON_HDR_SIZE + data_size);
   bmp_common_hdr_serialize(stream, BMP_PEER_UP_NOTIF, data_size);
-  bmp_per_peer_hdr_serialize(stream, is_peer_global,
-    false /* TODO: Hardcoded pre-policy Adj-RIB-In */, as4_support, remote_addr,
-    peer_as, peer_bgp_id, 0, 0); // 0, 0 - No timestamp provided
+  bmp_per_peer_hdr_serialize(stream, peer);
 
   bmp_put_ipa(stream, local_addr);
   bmp_put_u16(stream, local_port);
@@ -565,9 +534,8 @@ bmp_peer_up_notif_msg_serialize(buffer *stream, const bool is_peer_global,
 }
 
 static void
-bmp_peer_down_notif_msg_serialize(buffer *stream, const bool is_peer_global,
-  const u32 peer_as, const u32 peer_bgp_id, const bool as4_support,
-  const ip_addr remote_addr, const struct bmp_peer_down_info *info)
+bmp_peer_down_notif_msg_serialize(buffer *stream, const struct bmp_peer_hdr_info *peer,
+                                 const struct bmp_peer_down_info *info)
 {
   const size_t data_size = BMP_PER_PEER_HDR_SIZE + 1 +
     (((info->reason == BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION) ||
@@ -576,9 +544,7 @@ bmp_peer_down_notif_msg_serialize(buffer *stream, const bool is_peer_global,
 
   bmp_buffer_need(stream, BMP_COMMON_HDR_SIZE + data_size);
   bmp_common_hdr_serialize(stream, BMP_PEER_DOWN_NOTIF, data_size);
-  bmp_per_peer_hdr_serialize(stream, is_peer_global,
-    false /* TODO: Hardcoded pre-policy adj RIB IN */,  as4_support, remote_addr,
-    peer_as, peer_bgp_id, 0, 0); // 0, 0 - No timestamp provided
+  bmp_per_peer_hdr_serialize(stream, peer);
 
   bmp_put_u8(stream, info->reason);
 
@@ -895,12 +861,18 @@ bmp_send_peer_up_notif_msg(struct bmp_proto *p, const struct bgp_proto *bgp,
     return;
   }
 
-  const bool is_global_instance_peer = bmp_is_peer_global_instance(bgp);
+  struct bmp_peer_hdr_info peer = {
+    .address = bgp->remote_ip,
+    .as = bgp->remote_as,
+    .id = bgp->remote_id,
+    .global = bmp_is_peer_global_instance(bgp),
+    .policy = false,           // Hardcoded pre-policy Adj-RIB-In
+    .timestamp = 0,            // No timestamp provided
+  };
+
   buffer payload = bmp_default_buffer(p);
-  bmp_peer_up_notif_msg_serialize(&payload, is_global_instance_peer,
-    bgp->remote_as, bgp->remote_id, 1,
-    sk->saddr, sk->daddr, sk->sport, sk->dport, tx_data, tx_data_size,
-    rx_data, rx_data_size);
+  bmp_peer_up_notif_msg_serialize(&payload, &peer, sk->saddr, sk->sport, sk->dport,
+                                 tx_data, tx_data_size, rx_data, rx_data_size);
   bmp_schedule_tx_packet(p, payload.start, payload.pos - payload.start);
 }
 
@@ -908,18 +880,17 @@ static void
 bmp_route_monitor_put_update(struct bmp_proto *p, struct bmp_stream *bs, byte *data, size_t length, btime timestamp)
 {
   struct bgp_proto *bgp = bs->bgp;
-  const byte *start = bmp_route_monitor_msg_serialize(p,
-      bmp_is_peer_global_instance(bgp),
-      bmp_stream_policy(bs),
-      bgp->remote_as,
-      bgp->remote_id,
-      true,
-      bgp->remote_ip,
-      data,
-      length,
-      timestamp
-      );
 
+  struct bmp_peer_hdr_info peer = {
+    .address = bgp->remote_ip,
+    .as = bgp->remote_as,
+    .id = bgp->remote_id,
+    .global = bmp_is_peer_global_instance(bgp),
+    .policy = bmp_stream_policy(bs),
+    .timestamp = timestamp,
+  };
+
+  const byte *start = bmp_route_monitor_msg_serialize(p, &peer, data, length);
   bmp_schedule_tx_packet(p, start, (data - start) + length);
 }
 
@@ -962,12 +933,19 @@ bmp_send_peer_down_notif_msg(struct bmp_proto *p, const struct bgp_proto *bgp,
   ASSERT(p->started);
 
   const struct bgp_caps *remote_caps = bmp_get_bgp_remote_caps_ext(bgp);
-  bool is_global_instance_peer = bmp_is_peer_global_instance(bgp);
+
+  struct bmp_peer_hdr_info peer = {
+    .address = bgp->remote_ip,
+    .as = bgp->remote_as,
+    .id = bgp->remote_id,
+    .global = bmp_is_peer_global_instance(bgp),
+    .policy = false,           // Hardcoded pre-policy Adj-RIB-In
+    .no_as4 = remote_caps ? !remote_caps->as4_support : !bgp->as4_session,
+    .timestamp = 0,            // No timestamp provided
+  };
+
   buffer payload = bmp_default_buffer(p);
-  bmp_peer_down_notif_msg_serialize(&payload, is_global_instance_peer,
-    bgp->remote_as, bgp->remote_id,
-    remote_caps ? remote_caps->as4_support : bgp->as4_session,
-    bgp->remote_ip, info);
+  bmp_peer_down_notif_msg_serialize(&payload, &peer, info);
   bmp_schedule_tx_packet(p, payload.start, payload.pos - payload.start);
 }