]> git.proxmox.com Git - mirror_frr.git/commitdiff
bfdd,lib: simplify integration protocol
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Sun, 4 Oct 2020 21:02:24 +0000 (18:02 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Sun, 8 Nov 2020 15:06:32 +0000 (12:06 -0300)
Let the integration protocol always send the full configuration
instead of saving a few bytes. It will also allow protocols to specify
source address for IPv4 single hop connections and interface for multi
hop configuration.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
bfdd/ptm_adapter.c
lib/bfd.c

index 3a80d9203b49f3e694e1cc330d9cb4601f185a38..eef88af754c9977e5e4226db7153039b9ccba41c 100644 (file)
@@ -307,6 +307,8 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
 
        /*
         * Register/Deregister/Update Message format:
+        *
+        * Old format (being used by PTM BFD).
         * - header: Command, VRF
         * - l: pid
         * - w: family
@@ -322,16 +324,37 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
         *   - multihop:
         *     - w: family
         *       - AF_INET:
-        *         - l: destination ipv4
+        *         - l: source IPv4 address
         *       - AF_INET6:
-        *         - 16 bytes: destination IPv6
+        *         - 16 bytes: source IPv6 address
         *     - c: ttl
         *   - no multihop
         *     - AF_INET6:
         *       - w: family
-        *       - 16 bytes: ipv6 address
+        *       - 16 bytes: source IPv6 address
         *     - c: ifname length
         *     - X bytes: interface name
+        *
+        * New format:
+        * - header: Command, VRF
+        * - l: pid
+        * - w: family
+        *   - AF_INET:
+        *     - l: destination IPv4 address
+        *   - AF_INET6:
+        *     - 16 bytes: destination IPv6 address
+        * - l: min_rx
+        * - l: min_tx
+        * - c: detect multiplier
+        * - c: is_multihop?
+        * - w: family
+        *   - AF_INET:
+        *     - l: source IPv4 address
+        *   - AF_INET6:
+        *     - 16 bytes: source IPv6 address
+        * - c: ttl
+        * - c: ifname length
+        * - X bytes: interface name
         * - c: bfd_cbit
         * - c: profile name length.
         * - X bytes: profile name.
@@ -355,58 +378,50 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
        bpc->bpc_ipv4 = (bpc->bpc_peer.sa_sin.sin_family == AF_INET);
 
        /* Get peer configuration. */
-       if (command != ZEBRA_BFD_DEST_DEREGISTER) {
-               STREAM_GETL(msg, bpc->bpc_recvinterval);
-               bpc->bpc_has_recvinterval =
-                       (bpc->bpc_recvinterval != BPC_DEF_RECEIVEINTERVAL);
-
-               STREAM_GETL(msg, bpc->bpc_txinterval);
-               bpc->bpc_has_txinterval =
-                       (bpc->bpc_txinterval != BPC_DEF_TRANSMITINTERVAL);
-
-               STREAM_GETC(msg, bpc->bpc_detectmultiplier);
-               bpc->bpc_has_detectmultiplier =
-                       (bpc->bpc_detectmultiplier != BPC_DEF_DETECTMULTIPLIER);
-       }
+       STREAM_GETL(msg, bpc->bpc_recvinterval);
+       bpc->bpc_has_recvinterval =
+               (bpc->bpc_recvinterval != BPC_DEF_RECEIVEINTERVAL);
+
+       STREAM_GETL(msg, bpc->bpc_txinterval);
+       bpc->bpc_has_txinterval =
+               (bpc->bpc_txinterval != BPC_DEF_TRANSMITINTERVAL);
+
+       STREAM_GETC(msg, bpc->bpc_detectmultiplier);
+       bpc->bpc_has_detectmultiplier =
+               (bpc->bpc_detectmultiplier != BPC_DEF_DETECTMULTIPLIER);
 
        /* Read (single|multi)hop and its options. */
        STREAM_GETC(msg, bpc->bpc_mhop);
-       if (bpc->bpc_mhop) {
-               /* Read multihop source address and TTL. */
-               _ptm_msg_read_address(msg, &bpc->bpc_local);
-               STREAM_GETC(msg, bpc->bpc_minimum_ttl);
-               if (bpc->bpc_minimum_ttl >= BFD_TTL_VAL
-                   || bpc->bpc_minimum_ttl == 0) {
-                       zlog_warn("%s: received invalid TTL configuration %d",
-                                 __func__, bpc->bpc_has_minimum_ttl);
-                       bpc->bpc_minimum_ttl = BFD_DEF_MHOP_TTL;
-                       bpc->bpc_has_minimum_ttl = false;
-               } else {
-                       bpc->bpc_minimum_ttl =
-                               (BFD_TTL_VAL + 1) - bpc->bpc_minimum_ttl;
-                       bpc->bpc_has_minimum_ttl = true;
-               }
+
+       /* Read multihop source address and TTL. */
+       _ptm_msg_read_address(msg, &bpc->bpc_local);
+
+       /* Read the minimum TTL (0 means unset or invalid). */
+       STREAM_GETC(msg, bpc->bpc_minimum_ttl);
+       if (bpc->bpc_minimum_ttl == 0) {
+               bpc->bpc_minimum_ttl = BFD_DEF_MHOP_TTL;
+               bpc->bpc_has_minimum_ttl = false;
        } else {
-               /* If target is IPv6, then we must obtain local address. */
-               if (bpc->bpc_ipv4 == false)
-                       _ptm_msg_read_address(msg, &bpc->bpc_local);
+               bpc->bpc_minimum_ttl = (BFD_TTL_VAL + 1) - bpc->bpc_minimum_ttl;
+               bpc->bpc_has_minimum_ttl = true;
+       }
 
-               /*
-                * Read interface name and make sure it fits our data
-                * structure, otherwise fail.
-                */
-               STREAM_GETC(msg, ifnamelen);
-               if (ifnamelen >= sizeof(bpc->bpc_localif)) {
-                       zlog_err("ptm-read: interface name is too big");
-                       return -1;
-               }
+       /*
+        * Read interface name and make sure it fits our data
+        * structure, otherwise fail.
+        */
+       STREAM_GETC(msg, ifnamelen);
+       if (ifnamelen >= sizeof(bpc->bpc_localif)) {
+               zlog_err("ptm-read: interface name is too big");
+               return -1;
+       }
 
-               bpc->bpc_has_localif = ifnamelen > 0;
-               if (bpc->bpc_has_localif) {
-                       STREAM_GET(bpc->bpc_localif, msg, ifnamelen);
-                       bpc->bpc_localif[ifnamelen] = 0;
-               }
+       bpc->bpc_has_localif = ifnamelen > 0;
+       if (bpc->bpc_has_localif) {
+               STREAM_GET(bpc->bpc_localif, msg, ifnamelen);
+               bpc->bpc_localif[ifnamelen] = 0;
        }
+
        if (vrf_id != VRF_DEFAULT) {
                struct vrf *vrf;
 
@@ -424,6 +439,7 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
                strlcpy(bpc->bpc_vrfname, VRF_DEFAULT_NAME, sizeof(bpc->bpc_vrfname));
        }
 
+       /* Read control plane independant configuration. */
        STREAM_GETC(msg, bpc->bpc_cbit);
 
        /* Handle profile names. */
index d1a0ec671e505c3e7fbf0616774fb16e1320a337..088bcc431b571f244126a8cf3001ffd54e167caf 100644 (file)
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -468,6 +468,39 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args)
                                            : sizeof(struct in6_addr);
        stream_put(s, &args->dst, addrlen);
 
+       /*
+        * For more BFD integration protocol details, see function
+        * `_ptm_msg_read` in `bfdd/ptm_adapter.c`.
+        */
+#if HAVE_BFDD > 0
+       /* Session timers. */
+       stream_putl(s, args->min_rx);
+       stream_putl(s, args->min_tx);
+       stream_putc(s, args->detection_multiplier);
+
+       /* Is multi hop? */
+       stream_putc(s, args->mhop != 0);
+
+       /* Source address. */
+       stream_putw(s, args->family);
+       stream_put(s, &args->src, addrlen);
+
+       /* Send the expected TTL. */
+       stream_putc(s, args->ttl);
+
+       /* Send interface name if any. */
+       stream_putc(s, args->ifnamelen);
+       if (args->ifnamelen)
+               stream_put(s, args->ifname, args->ifnamelen);
+
+       /* Send the C bit indicator. */
+       stream_putc(s, args->cbit);
+
+       /* Send profile name if any. */
+       stream_putc(s, args->profilelen);
+       if (args->profilelen)
+               stream_put(s, args->profile, args->profilelen);
+#else /* PTM BFD */
        /* Encode timers if this is a registration message. */
        if (args->command != ZEBRA_BFD_DEST_DEREGISTER) {
                stream_putl(s, args->min_rx);
@@ -500,16 +533,6 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args)
                if (args->ifnamelen)
                        stream_put(s, args->ifname, args->ifnamelen);
        }
-
-       /* Send the C bit indicator. */
-       stream_putc(s, args->cbit);
-
-       /* `ptm-bfd` doesn't support profiles yet. */
-#if HAVE_BFDD > 0
-       /* Send profile name if any. */
-       stream_putc(s, args->profilelen);
-       if (args->profilelen)
-               stream_put(s, args->profile, args->profilelen);
 #endif /* HAVE_BFDD */
 
        /* Finish the message by writing the size. */