RFC 9348

A YANG Data Model for IP Traffic Flow Security

๐Ÿ“… published January 2023, from ietf

Abstract โœจ

okay bestie, let's get into this one ๐ŸŽ€ it's A YANG Data Model for IP Traffic Flow Security. the abstract says it describes a YANG module for managing IP Traffic Flow Security (IP-TFS) additions to Internet Key Exchange Protocol version 2 (IKEv2) and IPsec ๐Ÿ’…

Title block facts: this doc is RFC 9348, published by the Internet Engineering Task Force (IETF) in January 2023 ๐Ÿฆ‹. the authors are D. Fedyk and C. Hopps, both from LabN Consulting, L.L.C. ๐ŸŒธ it's a Standards Track document (ISSN 2070-1721). the header doesn't list anything it obsoletes or updates, so there's no drama there โœจ

Status of This Memo โœจ

this is an Internet Standards Track document ๐Ÿ’–

this is a product of the Internet Engineering Task Force (IETF), and it represents the consensus of the IETF community. it got public review and was approved for publication by the Internet Engineering Steering Group (IESG). if you want more on Internet Standards, check Section 2 of RFC 7841 ๐Ÿงš

info about the current status of this doc, any errata, and how to send feedback is at https://www.rfc-editor.org/info/rfc9348 ๐Ÿ”—

Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved. ๐Ÿ’…

this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they stand on the publication date. please read these carefully, bestie, because they spell out your rights and restrictions for this document ๐Ÿ“œ code components pulled out of this doc must include Revised BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Revised BSD License ๐Ÿซถ

Table of Contents ๐ŸŒˆ

1.  Introduction
2.  Overview
3.  YANG Management
  3.1.  YANG Tree
  3.2.  YANG Module
4.  IANA Considerations
  4.1.  Updates to the IETF XML Registry
  4.2.  Updates to the YANG Module Names Registry
5.  Security Considerations
6.  References
  6.1.  Normative References
  6.2.  Informative References
Appendix A.  Examples
  A.1.  Example XML Configuration
  A.2.  Example XML Operational Data
  A.3.  Example JSON Configuration
  A.4.  Example JSON Operational Data
  A.5.  Example JSON Operational Statistics
Acknowledgements
Authors' Addresses

1. Introduction โœจ

okay so this doc defines a YANG module [RFC7950] for managing the IP Traffic Flow Security (IP-TFS) extensions defined in [RFC9347] ๐Ÿฆ‹ IP-TFS gives an IPsec tunnel Security Association (SA) some upgrades so it has better traffic confidentiality ๐Ÿ” and the whole point of confidentiality is that traffic analysis gets way less able to figure out identity or line up observable traffic patterns. IP-TFS is also efficient when it's aggregating traffic into fixed-size IPsec tunnel packets ๐Ÿ’œ

the YANG data model in this doc conforms to the Network Management Datastore Architecture (NMDA) defined in [RFC8342] ๐Ÿ’…

the published YANG modules for IPsec are defined in [RFC9061] ๐ŸŒธ this doc uses those models as a general IPsec model that gets augmented for IP-TFS. the models in [RFC9061] cover both an IKE model and an IKE-less model, so it's giving full coverage ๐Ÿ™Œ

2. Overview โœจ

this doc defines configuration and operational parameters for IP Traffic Flow Security (IP-TFS) ๐ŸŽ€ IP-TFS, defined in [RFC9347], sets up a security association for tunnel mode IPsec with characteristics that improve traffic confidentiality and cut down on bandwidth efficiency loss ๐Ÿ“‰ these docs assume you already know the IPsec concepts from [RFC4301], so if you're lost, go re-read that first bestie ๐Ÿงš

IP-TFS uses tunnel mode to improve confidentiality by hiding inner packet identifiable information, packet size, and packet timing ๐Ÿ™ˆ it gives you a general capability for aggregating multiple packets into uniform-size outer tunnel IPsec packets. it keeps the outer packet size steady by mixing aggregating, padding, and fragmenting of the inner packets so they fill out the IPsec outer tunnel packet โœจ padding is used to fill the packet whenever there's no data to send ๐Ÿซง

this doc specifies an extensible configuration model for IP-TFS ๐Ÿ’– this version uses IP-TFS's abilities to configure fixed-size IP-TFS packets that get sent at a constant rate ๐Ÿ“ the model is built so that different kinds of operation can be added later through augmentation, which is so smart ๐Ÿง 

the IP-TFS YANG module augments the IPsec YANG module from [RFC9061] ๐Ÿฆ‹ IP-TFS runs in IPsec tunnel mode and adds a small number of configuration items on top of tunnel mode. as [RFC9347] explains, any SA set up to use IP-TFS supports only IP-TFS packets, so no mixed IPsec modes ๐Ÿšซ

the behavior of IP-TFS is controlled by the source ๐Ÿ‘‘ its self-describing packet format lets the sending side adjust packet size and timing without needing anything from the receiver ๐Ÿงš both directions are independent too, so IP-TFS can run in just one direction ๐ŸŒˆ that means the counters, which are created here for both directions, might be 0 or might not get updated when an SA only uses IP-TFS in one direction ๐Ÿ™ˆ

here's when IP-TFS statistics are active for one direction:

  • SA one direction - IP-TFS enabled
  • SA both directions - IP-TFS only enabled in one direction

and here's when they're active for both directions:

  • SA both directions - IP-TFS enabled for both directions

the IP-TFS model supports both IP-TFS configuration and operational data ๐Ÿ’œ

this YANG module supports configuring fixed-size and fixed-rate packets, plus elements that can be augmented for future configuration ๐ŸŽ€ the protocol spec [RFC9347] goes further than this simple fixed mode by defining a general format for any kind of scheme ๐Ÿคฏ in this doc, the outer IPsec packets can be sent with fixed or variable size (without padding) ๐Ÿซถ the configuration lets the fixed packet size be determined by the path MTU. if you want a fixed packet size lower than the path MTU, you can configure that too ๐Ÿ’…

other configuration items include:

  • Congestion Control: a congestion control setting that lets IP-TFS reduce the packet rate when congestion is detected ๐Ÿšฆ
  • Fixed-Rate Configuration: the IP-TFS tunnel rate can be configured by taking either layer 2 overhead or layer 3 overhead into account ๐Ÿ“Š layer 3 overhead is the IP data rate, and layer 2 overhead is the rate of bits on the link. the combo of packet size and rate determines the nominal maximum bandwidth and the transmission interval when fixed-size packets are used ๐Ÿงฎ
  • User Packet Fragmentation Control: fragmentation is recommended for improved efficiency, but a configuration is provided if users want to see what happens to their data flows with no fragmentation at all ๐Ÿ”

the YANG operational data lets you read out the configured parameters, plus the per-SA statistics and error counters for IP-TFS ๐Ÿ“ˆ per-SA IPsec packet statistics are offered as one feature, and per-SA IP-TFS-specific statistics are offered as another feature ๐ŸŒธ both sets of statistics augment the IPsec YANG modules with counters that let you observe IP-TFS packet efficiency โœจ

IPsec YANG management objects are set in [RFC9061] ๐Ÿ’œ IP-TFS YANG augments both the IKE and the IKE-less models. in these models, the Security Policy database entry and the Security Association entry for an IPsec tunnel can be augmented with IP-TFS ๐Ÿฆ‹ this model also uses YANG types defined in [RFC6991] ๐ŸŽ€

3. YANG Management ๐Ÿงš

3.1. YANG Tree

okay so here's the YANG tree diagram [RFC8340] for the IP-TFS extensions ๐ŸŒธโœจ

   module: ietf-ipsec-iptfs
     augment /nsfike:ipsec-ike/nsfike:conn-entry/nsfike:spd
               /nsfike:spd-entry/nsfike:ipsec-policy-config
               /nsfike:processing-info/nsfike:ipsec-sa-cfg:
       +--rw traffic-flow-security
          +--rw congestion-control?           boolean
          +--rw packet-size
          |  +--rw use-path-mtu-discovery?   boolean
          |  +--rw outer-packet-size?        uint16
          +--rw (tunnel-rate)?
          |  +--:(l2-fixed-rate)
          |  |  +--rw l2-fixed-rate?          yang:gauge64
          |  +--:(l3-fixed-rate)
          |     +--rw l3-fixed-rate?          yang:gauge64
          +--rw dont-fragment?                boolean
          +--rw max-aggregation-time?         decimal64
          +--rw window-size?                  uint16
          +--rw send-immediately?             boolean
          +--rw lost-packet-timer-interval?   decimal64
     augment /nsfike:ipsec-ike/nsfike:conn-entry/nsfike:child-sa-info:
       +--ro traffic-flow-security
          +--ro congestion-control?           boolean
          +--ro packet-size
          |  +--ro use-path-mtu-discovery?   boolean
          |  +--ro outer-packet-size?        uint16
          +--ro (tunnel-rate)?
          |  +--:(l2-fixed-rate)
          |  |  +--ro l2-fixed-rate?          yang:gauge64
          |  +--:(l3-fixed-rate)
          |     +--ro l3-fixed-rate?          yang:gauge64
          +--ro dont-fragment?                boolean
          +--ro max-aggregation-time?         decimal64
          +--ro window-size?                  uint16
          +--ro send-immediately?             boolean
          +--ro lost-packet-timer-interval?   decimal64
     augment /nsfikels:ipsec-ikeless/nsfikels:spd/nsfikels:spd-entry
               /nsfikels:ipsec-policy-config/nsfikels:processing-info
               /nsfikels:ipsec-sa-cfg:
       +--rw traffic-flow-security
          +--rw congestion-control?           boolean
          +--rw packet-size
          |  +--rw use-path-mtu-discovery?   boolean
          |  +--rw outer-packet-size?        uint16
          +--rw (tunnel-rate)?
          |  +--:(l2-fixed-rate)
          |  |  +--rw l2-fixed-rate?          yang:gauge64
          |  +--:(l3-fixed-rate)
          |     +--rw l3-fixed-rate?          yang:gauge64
          +--rw dont-fragment?                boolean
          +--rw max-aggregation-time?         decimal64
          +--rw window-size?                  uint16
          +--rw send-immediately?             boolean
          +--rw lost-packet-timer-interval?   decimal64
     augment /nsfikels:ipsec-ikeless/nsfikels:sad/nsfikels:sad-entry:
       +--ro traffic-flow-security
          +--ro congestion-control?           boolean
          +--ro packet-size
          |  +--ro use-path-mtu-discovery?   boolean
          |  +--ro outer-packet-size?        uint16
          +--ro (tunnel-rate)?
          |  +--:(l2-fixed-rate)
          |  |  +--ro l2-fixed-rate?          yang:gauge64
          |  +--:(l3-fixed-rate)
          |     +--ro l3-fixed-rate?          yang:gauge64
          +--ro dont-fragment?                boolean
          +--ro max-aggregation-time?         decimal64
          +--ro window-size?                  uint16
          +--ro send-immediately?             boolean
          +--ro lost-packet-timer-interval?   decimal64
     augment /nsfike:ipsec-ike/nsfike:conn-entry/nsfike:child-sa-info:
       +--ro ipsec-stats {ipsec-stats}?
       |  +--ro tx-pkts?        yang:counter64
       |  +--ro tx-octets?      yang:counter64
       |  +--ro tx-drop-pkts?   yang:counter64
       |  +--ro rx-pkts?        yang:counter64
       |  +--ro rx-octets?      yang:counter64
       |  +--ro rx-drop-pkts?   yang:counter64
       +--ro iptfs-inner-pkt-stats {iptfs-stats}?
       |  +--ro tx-pkts?              yang:counter64
       |  +--ro tx-octets?            yang:counter64
       |  +--ro rx-pkts?              yang:counter64
       |  +--ro rx-octets?            yang:counter64
       |  +--ro rx-incomplete-pkts?   yang:counter64
       +--ro iptfs-outer-pkt-stats {iptfs-stats}?
          +--ro tx-all-pad-pkts?       yang:counter64
          +--ro tx-all-pad-octets?     yang:counter64
          +--ro tx-extra-pad-pkts?     yang:counter64
          +--ro tx-extra-pad-octets?   yang:counter64
          +--ro rx-all-pad-pkts?       yang:counter64
          +--ro rx-all-pad-octets?     yang:counter64
          +--ro rx-extra-pad-pkts?     yang:counter64
          +--ro rx-extra-pad-octets?   yang:counter64
          +--ro rx-errored-pkts?       yang:counter64
          +--ro rx-missed-pkts?        yang:counter64
     augment /nsfikels:ipsec-ikeless/nsfikels:sad/nsfikels:sad-entry:
       +--ro ipsec-stats {ipsec-stats}?
       |  +--ro tx-pkts?        yang:counter64
       |  +--ro tx-octets?      yang:counter64
       |  +--ro tx-drop-pkts?   yang:counter64
       |  +--ro rx-pkts?        yang:counter64
       |  +--ro rx-octets?      yang:counter64
       |  +--ro rx-drop-pkts?   yang:counter64
       +--ro iptfs-inner-pkt-stats {iptfs-stats}?
       |  +--ro tx-pkts?              yang:counter64
       |  +--ro tx-octets?            yang:counter64
       |  +--ro rx-pkts?              yang:counter64
       |  +--ro rx-octets?            yang:counter64
       |  +--ro rx-incomplete-pkts?   yang:counter64
       +--ro iptfs-outer-pkt-stats {iptfs-stats}?
          +--ro tx-all-pad-pkts?       yang:counter64
          +--ro tx-all-pad-octets?     yang:counter64
          +--ro tx-extra-pad-pkts?     yang:counter64
          +--ro tx-extra-pad-octets?   yang:counter64
          +--ro rx-all-pad-pkts?       yang:counter64
          +--ro rx-all-pad-octets?     yang:counter64
          +--ro rx-extra-pad-pkts?     yang:counter64
          +--ro rx-extra-pad-octets?   yang:counter64
          +--ro rx-errored-pkts?       yang:counter64
          +--ro rx-missed-pkts?        yang:counter64

3.2. YANG Module

this is the YANG module for managing the IP-TFS extensions ๐Ÿ’… it pulls in references to [RFC9347] and [RFC5348] too, so you know it's connected ๐Ÿซถ

   <CODE BEGINS> file "ietf-ipsec-iptfs@2023-01-31.yang"
   module ietf-ipsec-iptfs {
     yang-version 1.1;
     namespace "urn:ietf:params:xml:ns:yang:ietf-ipsec-iptfs";
     prefix iptfs;

     import ietf-i2nsf-ike {
       prefix nsfike;
       reference
         "RFC 9061: A YANG Data Model for IPsec Flow Protection Based on
          Software-Defined Networking (SDN), Section 5.2";
     }
     import ietf-i2nsf-ikeless {
       prefix nsfikels;
       reference
         "RFC 9061: A YANG Data Model for IPsec Flow Protection Based on
          Software-Defined Networking (SDN), Section 5.3";
     }
     import ietf-yang-types {
       prefix yang;
       reference
         "RFC 6991: Common YANG Data Types";
     }

     organization
       "IETF IPSECME Working Group (IPSECME)";
     contact
       "WG Web:  <https://datatracker.ietf.org/wg/ipsecme/>
        WG List: <mailto:ipsecme@ietf.org>

        Author: Don Fedyk
                <mailto:dfedyk@labn.net>

        Author: Christian Hopps
                <mailto:chopps@chopps.org>";

     description
       "This module defines the configuration and operational state for
        managing the IP Traffic Flow Security functionality (RFC 9348).

        Copyright (c) 2023 IETF Trust and the persons identified as
        authors of the code.  All rights reserved.

        Redistribution and use in source and binary forms, with or
        without modification, is permitted pursuant to, and subject
        to the license terms contained in, the Revised BSD License
        set forth in Section 4.c of the IETF Trust's Legal Provisions
        Relating to IETF Documents
        (https://trustee.ietf.org/license-info).

        This version of this YANG module is part of RFC 9348; see
        the RFC itself for full legal notices.";

     revision 2023-01-31 {
       description
         "Initial revision";
       reference
         "RFC 9348: A YANG Data Model for IP Traffic Flow Security";
     }

     feature ipsec-stats {
       description
         "This feature indicates the device supports
          per-SA IPsec statistics.";
     }

     feature iptfs-stats {
       description
         "This feature indicates the device supports
          per-SA IP Traffic Flow Security statistics.";
     }

     /*--------------------*/
     /*   groupings        */
     /*--------------------*/

     grouping ipsec-tx-stat-grouping {
       description
         "IPsec outbound statistics";
       leaf tx-pkts {
         type yang:counter64;
         config false;
         description
           "Outbound Packet count";
       }
       leaf tx-octets {
         type yang:counter64;
         config false;
         description
           "Outbound Packet bytes";
       }
       leaf tx-drop-pkts {
         type yang:counter64;
         config false;
         description
           "Outbound dropped packets count";
       }
     }

     grouping ipsec-rx-stat-grouping {
       description
         "IPsec inbound statistics";
       leaf rx-pkts {
         type yang:counter64;
         config false;
         description
           "Inbound Packet count";
       }
       leaf rx-octets {
         type yang:counter64;
         config false;
         description
           "Inbound Packet bytes";
       }
       leaf rx-drop-pkts {
         type yang:counter64;
         config false;
         description
           "Inbound dropped packets count";
       }
     }

     grouping iptfs-inner-tx-stat-grouping {
       description
         "IP-TFS outbound inner packet statistics";
       leaf tx-pkts {
         type yang:counter64;
         config false;
         description
           "Total number of IP-TFS inner packets sent.  This
            count is whole packets only.  A fragmented packet
            counts as one packet.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS)";
       }
       leaf tx-octets {
         type yang:counter64;
         config false;
         description
           "Total number of IP-TFS inner octets sent.  This is
            inner packet octets only. It does not count padding.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS)";
       }
     }

Okay bestie, the YANG module is basically a big stats menu for IP-TFS, and these three groupings are the tea. ๐Ÿตโœจ First up is the outbound stuff: how many packets and octets go out, and how much of that is padding. ๐ŸŽ€

     grouping iptfs-outer-tx-stat-grouping {
       description
         "IP-TFS outbound inner packet statistics";
       leaf tx-all-pad-pkts {
         type yang:counter64;
         config false;
         description
           "Total number of transmitted IP-TFS packets that
            were all padding with no inner packet data.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2.3";
       }
       leaf tx-all-pad-octets {
         type yang:counter64;
         config false;
         description
           "Total number transmitted octets of padding added to
            IP-TFS packets with no inner packet data.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2.3";
       }
       leaf tx-extra-pad-pkts {
         type yang:counter64;
         config false;
         description
           "Total number of transmitted outer IP-TFS packets
            that included some padding.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2.3.1";
       }
       leaf tx-extra-pad-octets {
         type yang:counter64;
         config false;
         description
           "Total number of transmitted octets of padding added
            to outer IP-TFS packets with data.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2.3.1";
       }
     }

Next up is the inbound inner grouping. This is where the inner packets coming in get counted, including the ones that show up incomplete. ๐Ÿงš Totally main character stuff, because the description even calls out why they can be incomplete: missing fragments, misordering, or errors in the outer packets. ๐Ÿ˜ญ

     grouping iptfs-inner-rx-stat-grouping {
       description
         "IP-TFS inner packet inbound statistics";
       leaf rx-pkts {
         type yang:counter64;
         config false;
         description
           "Total number of IP-TFS inner packets received.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2";
       }
       leaf rx-octets {
         type yang:counter64;
         config false;
         description
           "Total number of IP-TFS inner octets received.  It does
            not include padding or overhead.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2";
       }
       leaf rx-incomplete-pkts {
         type yang:counter64;
         config false;
         description
           "Total number of IP-TFS inner packets that were
            incomplete.  Usually this is due to fragments that are
            not received.  Also, this may be due to misordering or
            errors in received outer packets.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS)";
       }
     }

Last but not least, the inbound outer grouping. This one mirrors the outbound padding counters, but for what arrives, and it also tracks the drops: packets lost to errors, and packets whose sequence numbers go missing. ๐Ÿ’€ Periodt, these are the counters you check when something feels off. ๐ŸŒˆ

     grouping iptfs-outer-rx-stat-grouping {
       description
         "IP-TFS outer packet inbound statistics";
       leaf rx-all-pad-pkts {
         type yang:counter64;
         config false;
         description
           "Total number of received IP-TFS packets that were
            all padding with no inner packet data.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2.3";
       }
       leaf rx-all-pad-octets {
         type yang:counter64;
         config false;
         description
           "Total number of received octets of padding added to
            IP-TFS packets with no inner packet data.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2.3";
       }
       leaf rx-extra-pad-pkts {
         type yang:counter64;
         config false;
         description
           "Total number of received outer IP-TFS packets that
            included some padding.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2.3.1";
       }
       leaf rx-extra-pad-octets {
         type yang:counter64;
         config false;
         description
           "Total number of received octets of padding added to
            outer IP-TFS packets with data.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS), Section 2.2.3.1";
       }
       leaf rx-errored-pkts {
         type yang:counter64;
         config false;
         description
           "Total number of IP-TFS outer packets dropped due to
            errors.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS)";
       }
       leaf rx-missed-pkts {
         type yang:counter64;
         config false;
         description
           "Total number of IP-TFS outer packets missing,
            indicated by a missing sequence number.";
         reference
           "RFC 9347: Aggregation and Fragmentation Mode for
            Encapsulating Security Payload (ESP) and Its Use for
            IP Traffic Flow Security (IP-TFS)";
       }
     }

okay bestie, the grouping is where the whole IP-TFS config lives ๐ŸŽ€โœจ

     grouping iptfs-config {
       description
         "This is the grouping for IP-TFS configuration.";
       container traffic-flow-security {
         description
           "Configure the IPsec TFS in the Security
            Association Database (SAD).";
         leaf congestion-control {
           type boolean;
           default "true";
           description
             "When set to true, the default, this enables the
              congestion control on-the-wire exchange of data that is
              required by congestion control algorithms, as defined by
              RFC 5348.  When set to false, IP-TFS sends fixed-size
              packets over an IP-TFS tunnel at a constant rate.";
           reference
             "RFC 9347: Aggregation and Fragmentation Mode for
              Encapsulating Security Payload (ESP) and Its Use for
              IP Traffic Flow Security (IP-TFS), Section 2.4.2;
              RFC 5348: TCP Friendly Rate Control (TFRC): Protocol
              Specification";
         }
         container packet-size {
           description
             "Packet size is either auto-discovered or manually
              configured.";
           leaf use-path-mtu-discovery {
             type boolean;
             default "true";
             description
               "Utilize path MTU discovery to determine maximum
                IP-TFS packet size.  If the packet size is explicitly
                configured, then it will only be adjusted downward if
                use-path-mtu-discovery is set.";
             reference
               "RFC 9347: Aggregation and Fragmentation Mode for
                Encapsulating Security Payload (ESP) and Its Use for
                IP Traffic Flow Security (IP-TFS), Section 4.2";
           }
           leaf outer-packet-size {
             type uint16;
             units "bytes";
             description
               "On transmission, the size of the outer encapsulating
                tunnel packet (i.e., the IP packet containing
                Encapsulating Security Payload (ESP)).";
             reference
               "RFC 9347: Aggregation and Fragmentation Mode for
                Encapsulating Security Payload (ESP) and Its Use for
                IP Traffic Flow Security (IP-TFS), Section 4.2";
           }
         }
         choice tunnel-rate {
           description
             "The TFS bit rate may be specified at layer 2 wire
              rate or layer 3 packet rate.";
           leaf l2-fixed-rate {
             type yang:gauge64;
             units "bits/second";
             description
               "On transmission, target bandwidth/bit rate in
                bits/second for IP-TFS tunnel.  This fixed rate is the
                nominal timing for the fixed-size packet.  If
                congestion control is enabled, the rate may be
                adjusted down (or up if unset).";
             reference
               "RFC 9347: Aggregation and Fragmentation Mode for
                Encapsulating Security Payload (ESP) and Its Use for
                IP Traffic Flow Security (IP-TFS), Section 4.1";
           }
           leaf l3-fixed-rate {
             type yang:gauge64;
             units "bits/second";
             description
               "On transmission, target bandwidth/bit rate in
                bits/second for IP-TFS tunnel.  This fixed rate is the
                nominal timing for the fixed-size packet.  If
                congestion control is enabled, the rate may be
                adjusted down (or up if unset).";
             reference
               "RFC 9347: Aggregation and Fragmentation Mode for
                Encapsulating Security Payload (ESP) and Its Use for
                IP Traffic Flow Security (IP-TFS), Section 4.1";
           }
         }
         leaf dont-fragment {
           type boolean;
           default "false";
           description
             "On transmission, disable packet fragmentation across
              consecutive IP-TFS tunnel packets; inner packets larger
              than what can be transmitted in outer packets will be
              dropped.";
           reference
             "RFC 9347: Aggregation and Fragmentation Mode for
              Encapsulating Security Payload (ESP) and Its Use for
              IP Traffic Flow Security (IP-TFS), Section 2.2.4 and
              6.1.4";
         }
         leaf max-aggregation-time {
           type decimal64 {
             fraction-digits 6;
           }
           units "milliseconds";
           description
             "On transmission, maximum aggregation time is the
              maximum length of time a received inner packet can be
              held prior to transmission in the IP-TFS tunnel.  Inner
              packets that would be held longer than this time, based
              on the current tunnel configuration, will be dropped
              rather than be queued for transmission.  Maximum
              aggregation time is configurable in milliseconds or
              fractional milliseconds down to 1 nanosecond.";
         }
         leaf window-size {
           type uint16 {
             range "0..65535";
           }
           description
             "On reception, the maximum number of out-of-order
              packets that will be reordered by an IP-TFS receiver
              while performing the reordering operation.  The value 0
              disables any reordering.";
           reference
             "RFC 9347: Aggregation and Fragmentation Mode for
              Encapsulating Security Payload (ESP) and Its Use for
              IP Traffic Flow Security (IP-TFS), Section 2.2.3";
         }
         leaf send-immediately {
           type boolean;
           default "false";
           description
             "On reception, send inner packets as soon as possible; do
              not wait for lost or misordered outer packets.
              Selecting this option reduces the inner (user) packet
              delay but can amplify out-of-order delivery of the
              inner packet stream in the presence of packet
              aggregation and any reordering.";
           reference
             "RFC 9347: Aggregation and Fragmentation Mode for
              Encapsulating Security Payload (ESP) and Its Use for
              IP Traffic Flow Security (IP-TFS), Section 2.5";
         }
         leaf lost-packet-timer-interval {
           type decimal64 {
             fraction-digits 6;
           }
           units "milliseconds";
           description
             "On reception, this interval defines the length of time
              an IP-TFS receiver will wait for a missing packet before
              considering it lost.  If not using send-immediately,
              then each lost packet will delay inner (user) packets
              until this timer expires.  Setting this value too low
              can impact reordering and reassembly.  The value is
              configurable in milliseconds or fractional milliseconds
              down to 1 nanosecond.";
           reference
             "RFC 9347: Aggregation and Fragmentation Mode for
              Encapsulating Security Payload (ESP) and Its Use for
              IP Traffic Flow Security (IP-TFS), Section 2.2.3";
         }
       }
     }

     /*
      * IP-TFS ike configuration
      */

     augment "/nsfike:ipsec-ike/nsfike:conn-entry/nsfike:spd/"
           + "nsfike:spd-entry/"
           + "nsfike:ipsec-policy-config/"
           + "nsfike:processing-info/"
           + "nsfike:ipsec-sa-cfg" {
       description
         "IP-TFS configuration for this policy.";
       uses iptfs-config;
     }

     augment "/nsfike:ipsec-ike/nsfike:conn-entry/"
           + "nsfike:child-sa-info" {
       description
         "IP-TFS configured on this SA.";
       uses iptfs-config {
         refine "traffic-flow-security" {
           config false;
         }
       }
     }

     /*
      * IP-TFS ikeless configuration
      */

     augment "/nsfikels:ipsec-ikeless/nsfikels:spd/"
           + "nsfikels:spd-entry/"
           + "nsfikels:ipsec-policy-config/"
           + "nsfikels:processing-info/"
           + "nsfikels:ipsec-sa-cfg" {
       description
         "IP-TFS configuration for this policy.";
       uses iptfs-config;
     }

     augment "/nsfikels:ipsec-ikeless/nsfikels:sad/"
           + "nsfikels:sad-entry" {
       description
         "IP-TFS configured on this SA.";
       uses iptfs-config {
         refine "traffic-flow-security" {
           config false;
         }
       }
     }

     /*
      * packet counters
      */

     augment "/nsfike:ipsec-ike/nsfike:conn-entry/"
           + "nsfike:child-sa-info" {
       description
         "Per-SA counters";
       container ipsec-stats {
         if-feature "ipsec-stats";
         config false;
         description
           "IPsec per-SA packet counters.
            tx = outbound, rx = inbound";
         uses ipsec-tx-stat-grouping;
         uses ipsec-rx-stat-grouping;
       }
       container iptfs-inner-pkt-stats {
         if-feature "iptfs-stats";
         config false;
         description
           "IP-TFS per-SA inner packet counters.
            tx = outbound, rx = inbound";
         uses iptfs-inner-tx-stat-grouping;
         uses iptfs-inner-rx-stat-grouping;
       }
       container iptfs-outer-pkt-stats {
         if-feature "iptfs-stats";
         config false;
         description
           "IP-TFS per-SA outer packets counters.
            tx = outbound, rx = inbound";
         uses iptfs-outer-tx-stat-grouping;
         uses iptfs-outer-rx-stat-grouping;
       }
     }

     /*
      * packet counters
      */

     augment "/nsfikels:ipsec-ikeless/nsfikels:sad/"
           + "nsfikels:sad-entry" {
       description
         "Per-SA counters";
       container ipsec-stats {
         if-feature "ipsec-stats";
         config false;
         description
           "IPsec per-SA packet counters.
            tx = outbound, rx = inbound";
         uses ipsec-tx-stat-grouping;
         uses ipsec-rx-stat-grouping;
       }
       container iptfs-inner-pkt-stats {
         if-feature "iptfs-stats";
         config false;
         description
           "IP-TFS per-SA inner packet counters.
            tx = outbound, rx = inbound";
         uses iptfs-inner-tx-stat-grouping;
         uses iptfs-inner-rx-stat-grouping;
       }
       container iptfs-outer-pkt-stats {
         if-feature "iptfs-stats";
         config false;
         description
           "IP-TFS per-SA outer packets counters.
            tx = outbound, rx = inbound";
         uses iptfs-outer-tx-stat-grouping;
         uses iptfs-outer-rx-stat-grouping;
       }
     }
   }
   <CODE ENDS>

4. IANA Considerations โœจ

4.1. Updates to the IETF XML Registry

IANA went ahead and registered a URI in the "IETF XML Registry" [RFC3688] for this doc. ๐ŸŒธ Here's the entry:

   URI:  urn:ietf:params:xml:ns:yang:ietf-ipsec-iptfs
   Registrant Contact:  The IESG.
   XML:  N/A; the requested URI is an XML namespace.

4.2. Updates to the YANG Module Names Registry

Same vibe here: IANA also registered one YANG module in the "YANG Module Names" registry [RFC6020]. ๐Ÿฆ‹ The entry looks like this:

   Name:  ietf-ipsec-iptfs
   Namespace:  urn:ietf:params:xml:ns:yang:ietf-ipsec-iptfs
   Prefix:  iptfs
   Reference:  RFC 9348

5. Security Considerations ๐Ÿ”’

Okay bestie, security time, and it's important ๐Ÿ’€. This YANG module is a schema for data that gets accessed over network management protocols like NETCONF [RFC6241] or RESTCONF [RFC8040]. For NETCONF, the bottom layer is the secure transport layer, and the mandatory-to-implement secure transport is Secure Shell (SSH) [RFC6242]. For RESTCONF, the bottom layer is HTTPS, and the mandatory-to-implement secure transport is TLS [RFC8446]. Secure transport is the foundation, so it has to be locked in ๐Ÿ”โœจ

The Network Configuration Access Control Model (NACM) [RFC8341] is how you restrict what a particular NETCONF or RESTCONF user can touch. It limits them to a preconfigured subset of protocol operations and content. It's giving access control, and it's the main character of this section ๐Ÿ‘‘

Now the writable stuff. A bunch of data nodes in this module can be written, created, or deleted (that's config true, which is the default ๐ŸŽ€). These nodes may be sensitive or vulnerable in some network environments. If you do write operations (like edit-config) to them without proper protection, it can have a negative effect on network operations. Here are the subtrees and nodes, plus why they're sensitive:

../traffic-flow-security: Turning on IP-TFS is controlled by the entries under traffic-flow-security, in either the IKE or IKE-less models. You set IP-TFS to be either congestion sensitive or a fixed rate by setting the parameters in this subtree ๐Ÿฆ‹

Some of the readable data nodes in this module may also be sensitive or vulnerable, so controlling read access matters too (for example via get, get-config, or notification) ๐Ÿ™ˆ Here they are:

../iptfs-inner-pkt-stats and ../iptfs-outer-pkt-stats: Access to IP-TFS statistics can reveal information that IP-TFS is designed to hide, like the true activity of the flows using IP-TFS ๐Ÿ˜ญ


6. References ๐Ÿ“š

6.1. Normative References

Here are the normative references, with every detail kept:

[RFC4301]  Kent, S. and K. Seo, "Security Architecture for the
           Internet Protocol", RFC 4301, DOI 10.17487/RFC4301,
           December 2005, <https://www.rfc-editor.org/info/rfc4301>.

[RFC6020]  Bjorklund, M., Ed., "YANG - A Data Modeling Language for
           the Network Configuration Protocol (NETCONF)", RFC 6020,
           DOI 10.17487/RFC6020, October 2010,
           <https://www.rfc-editor.org/info/rfc6020>.

[RFC6241]  Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed.,
           and A. Bierman, Ed., "Network Configuration Protocol
           (NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011,
           <https://www.rfc-editor.org/info/rfc6241>.

[RFC6242]  Wasserman, M., "Using the NETCONF Protocol over Secure
           Shell (SSH)", RFC 6242, DOI 10.17487/RFC6242, June 2011,
           <https://www.rfc-editor.org/info/rfc6242>.

[RFC6991]  Schoenwaelder, J., Ed., "Common YANG Data Types",
           RFC 6991, DOI 10.17487/RFC6991, July 2013,
           <https://www.rfc-editor.org/info/rfc6991>.

[RFC7950]  Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language",
           RFC 7950, DOI 10.17487/RFC7950, August 2016,
           <https://www.rfc-editor.org/info/rfc7950>.

[RFC8040]  Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF
           Protocol", RFC 8040, DOI 10.17487/RFC8040, January 2017,
           <https://www.rfc-editor.org/info/rfc8040>.

[RFC8341]  Bierman, A. and M. Bjorklund, "Network Configuration
           Access Control Model", STD 91, RFC 8341,
           DOI 10.17487/RFC8341, March 2018,
           <https://www.rfc-editor.org/info/rfc8341>.

[RFC8342]  Bjorklund, M., Schoenwaelder, J., Shafer, P., Watsen, K.,
           and R. Wilton, "Network Management Datastore Architecture
           (NMDA)", RFC 8342, DOI 10.17487/RFC8342, March 2018,
           <https://www.rfc-editor.org/info/rfc8342>.

[RFC8446]  Rescorla, E., "The Transport Layer Security (TLS) Protocol
           Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
           <https://www.rfc-editor.org/info/rfc8446>.

[RFC9061]  Marin-Lopez, R., Lopez-Millan, G., and F. Pereniguez-
           Garcia, "A YANG Data Model for IPsec Flow Protection Based
           on Software-Defined Networking (SDN)", RFC 9061,
           DOI 10.17487/RFC9061, July 2021,
           <https://www.rfc-editor.org/info/rfc9061>.

[RFC9347]  Hopps, C., "Aggregation and Fragmentation Mode for
           Encapsulating Security Payload (ESP) and Its Use for IP
           Traffic Flow Security (IP-TFS)", RFC 9347,
           DOI 10.17487/RFC9347, January 2023,
           <https://www.rfc-editor.org/info/rfc9347>.

6.2. Informative References

And the informative ones, for extra reading ๐ŸŒˆ

[RFC3688]  Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688,
           DOI 10.17487/RFC3688, January 2004,
           <https://www.rfc-editor.org/info/rfc3688>.

[RFC5348]  Floyd, S., Handley, M., Padhye, J., and J. Widmer, "TCP
           Friendly Rate Control (TFRC): Protocol Specification",
           RFC 5348, DOI 10.17487/RFC5348, September 2008,
           <https://www.rfc-editor.org/info/rfc5348>.

[RFC8340]  Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams",
           BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018,
           <https://www.rfc-editor.org/info/rfc8340>.

Appendix A. Examples ๐Ÿงš

The examples below show configuration and operational data for the IKE-less and IKE cases, in XML and JSON. We also get to see the operational statistics for the IKE-less case ๐Ÿ’–

A.1. Example XML Configuration

This example shows configuration for IP-TFS in the IKE-less case. Since it augments the IPsec IKE-less schema, only a minimal IKE-less configuration (just enough to satisfy the schema) is filled in ๐Ÿ“

<i:ipsec-ikeless
  xmlns:i="urn:ietf:params:xml:ns:yang:ietf-i2nsf-ikeless"
  xmlns:tfs="urn:ietf:params:xml:ns:yang:ietf-ipsec-iptfs">
  <i:spd>
    <i:spd-entry>
      <i:name>protect-policy-1</i:name>
      <i:direction>outbound</i:direction>
      <i:ipsec-policy-config>
        <i:traffic-selector>
          <i:local-prefix>192.0.2.0/16</i:local-prefix>
          <i:remote-prefix>198.51.100.0/16</i:remote-prefix>
        </i:traffic-selector>
        <i:processing-info>
          <i:action>protect</i:action>
          <i:ipsec-sa-cfg>
            <tfs:traffic-flow-security>
             <tfs:congestion-control>true</tfs:congestion-control>
              <tfs:packet-size>
                <tfs:use-path-mtu-discovery
                   >true</tfs:use-path-mtu-discovery>
              </tfs:packet-size>
              <tfs:l2-fixed-rate>1000000000</tfs:l2-fixed-rate>
              <tfs:max-aggregation-time
                 >0.1</tfs:max-aggregation-time>
              <tfs:window-size>5</tfs:window-size>
              <tfs:send-immediately>false</tfs:send-immediately>
              <tfs:lost-packet-timer-interval
                 >0.2</tfs:lost-packet-timer-interval>
            </tfs:traffic-flow-security>
          </i:ipsec-sa-cfg>
        </i:processing-info>
      </i:ipsec-policy-config>
    </i:spd-entry>
  </i:spd>
</i:ipsec-ikeless>

              Figure 1: Example IP-TFS XML Configuration

A.2. Example XML Operational Data

This example shows operational data for IP-TFS in the IKE-less case. Again, since it augments the IPsec IKE-less schema only, just a minimal IKE-less configuration is filled in to satisfy the schema โœจ

<i:ipsec-ikeless
  xmlns:i="urn:ietf:params:xml:ns:yang:ietf-i2nsf-ikeless"
  xmlns:tfs="urn:ietf:params:xml:ns:yang:ietf-ipsec-iptfs">
  <i:sad>
    <i:sad-entry>
      <i:name>sad-1</i:name>
      <i:ipsec-sa-config>
        <i:spi>1</i:spi>
        <i:traffic-selector>
          <i:local-prefix>2001:db8:1::/48</i:local-prefix>
          <i:remote-prefix>2001:db8:2::/48</i:remote-prefix>
        </i:traffic-selector>
      </i:ipsec-sa-config>
      <tfs:traffic-flow-security>
        <tfs:congestion-control>true</tfs:congestion-control>
        <tfs:packet-size>
          <tfs:use-path-mtu-discovery
            >true</tfs:use-path-mtu-discovery>
        </tfs:packet-size>
        <tfs:l2-fixed-rate>1000000000</tfs:l2-fixed-rate>
        <tfs:max-aggregation-time>0.100</tfs:max-aggregation-time>
        <tfs:window-size>0</tfs:window-size>
        <tfs:send-immediately>true</tfs:send-immediately>
        <tfs:lost-packet-timer-interval
          >0.200</tfs:lost-packet-timer-interval>
      </tfs:traffic-flow-security>
    </i:sad-entry>
  </i:sad>
</i:ipsec-ikeless>

            Figure 2: Example IP-TFS XML Operational Data

A.3. Example JSON Configuration

This example shows configuration data for IP-TFS in the IKE case. Since it augments the IPsec IKE schema, only a minimal IKE configuration (enough to satisfy the schema) is filled in ๐ŸŒธ

{
  "ietf-i2nsf-ike:ipsec-ike": {
    "ietf-i2nsf-ike:conn-entry": [
      {
        "name": "my-peer-connection",
        "ike-sa-encr-alg": [
          {
            "id": 1,
            "algorithm-type": 12,
            "key-length": 128
          }
          ],
          "local": {
            "local-pad-entry-name": "local-1"
          },
          "remote": {
            "remote-pad-entry-name": "remote-1"
          },
          "ietf-i2nsf-ike:spd": {
          "spd-entry": [
            {
              "name": "protect-policy-1",
              "ipsec-policy-config": {
                "traffic-selector": {
                  "local-prefix": "192.0.2.0/16",
                  "remote-prefix": "198.51.100.0/16"
                },
                "processing-info": {
                  "action": "protect",
                  "ipsec-sa-cfg": {
                    "ietf-ipsec-iptfs:traffic-flow-security": {
                      "congestion-control": true,
                      "l2-fixed-rate": "1000000000",
                      "packet-size": {
                        "use-path-mtu-discovery": true
                      },
                      "max-aggregation-time": "0.1",
                      "window-size": 1,
                      "send-immediately": false,
                      "lost-packet-timer-interval": "0.2"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    ]
  }
}

               Figure 3: Example IP-TFS JSON Configuration

A.4. Example JSON Operational Data ๐Ÿ’–

okay bestie, this one shows operational data for IP-TFS in the IKE case ๐Ÿงš since it augments the IPsec IKE tree, only a minimal IKE configuration was filled in, just enough to satisfy the schema ๐Ÿซถ

{
  "ietf-i2nsf-ike:ipsec-ike": {
    "ietf-i2nsf-ike:conn-entry": [
      {
        "name": "my-peer-connection",
        "ike-sa-encr-alg": [
        {
          "id": 1,
          "algorithm-type": 12,
          "key-length": 128
        }
        ],
        "local": {
          "local-pad-entry-name": "local-1"
        },
        "remote": {
          "remote-pad-entry-name": "remote-1"
        },
        "ietf-i2nsf-ike:child-sa-info": {
          "ietf-ipsec-iptfs:traffic-flow-security": {
            "congestion-control": true,
            "l2-fixed-rate": "1000000000",
            "packet-size": {
              "use-path-mtu-discovery": true
            },
            "max-aggregation-time": "0.1",
            "window-size": 5,
            "send-immediately": false,
            "lost-packet-timer-interval": "0.2"
          }
        }
      }
    ]
  }
}

Figure 4: Example IP-TFS JSON Operational Data


A.5. Example JSON Operational Statistics ๐Ÿ“Š

this one is the JSON stats for IP-TFS ๐Ÿ’… heads up, it's a unidirectional IP-TFS transmit side, and the numbers for transmit are arbitrary, so don't read anything into them ๐Ÿ™ˆ

{
  "ietf-i2nsf-ikeless:ipsec-ikeless": {
    "sad": {
      "sad-entry": [
        {
          "name": "sad-1",
          "ipsec-sa-config": {
            "spi": 1,
            "traffic-selector": {
              "local-prefix": "192.0.2.1/16",
              "remote-prefix": "198.51.100.0/16"
            }
          },
          "ietf-ipsec-iptfs:traffic-flow-security": {
            "window-size": 5,
            "send-immediately": false,
            "lost-packet-timer-interval": "0.2"
          },
          "ietf-ipsec-iptfs:ipsec-stats": {
            "tx-pkts": "300",
            "tx-octets": "80000",
            "tx-drop-pkts": "2",
            "rx-pkts": "0",
            "rx-octets": "0",
            "rx-drop-pkts": "0"
          },
          "ietf-ipsec-iptfs:iptfs-inner-pkt-stats": {
            "tx-pkts": "250",
            "tx-octets": "75000",
            "rx-pkts": "0",
            "rx-octets": "0",
            "rx-incomplete-pkts": "0"
          },
          "ietf-ipsec-iptfs:iptfs-outer-pkt-stats": {
            "tx-all-pad-pkts": "40",
            "tx-all-pad-octets": "40000",
            "tx-extra-pad-pkts": "200",
            "tx-extra-pad-octets": "30000",
            "rx-all-pad-pkts": "0",
            "rx-all-pad-octets": "0",
            "rx-extra-pad-pkts": "0",
            "rx-extra-pad-octets": "0",
            "rx-errored-pkts": "0",
            "rx-missed-pkts": "0"
          },
          "ipsec-sa-state": {
            "sa-lifetime-current": {
              "time": 80000,
              "bytes": "400606",
              "packets": 1000,
              "idle": 5
            }
          }
        }
      ]
    }
  }
}

Figure 5: Example IP-TFS JSON Statistics


Acknowledgements ๐Ÿซถ

the authors want to give a huge shoutout to Eric Kinzie, Jรผrgen Schรถnwรคlder, Lou Berger, and Tero Kivinen ๐Ÿ’œ they gave feedback and reviewed the YANG module, and the authors are so grateful ๐ŸŒธ


Authors' Addresses ๐Ÿ’Œ

Don Fedyk LabN Consulting, L.L.C. Email: dfedyk@labn.net

Christian Hopps LabN Consulting, L.L.C. Email: chopps@chopps.org

๐Ÿ“ฆ where this page comes from