netconfcentral logo

bbf-l2-forwarding@2018-12-03



  module bbf-l2-forwarding {

    yang-version 1.1;

    namespace
      "urn:bbf:yang:bbf-l2-forwarding";

    prefix bbf-l2-fwd;

    include bbf-l2-forwarding-base;
    include bbf-l2-forwarding-flooding-policies;
    include bbf-l2-forwarding-forwarders;
    include bbf-l2-forwarding-forwarding-databases;
    include bbf-l2-forwarding-mac-learning;
    include bbf-l2-forwarding-split-horizon-profiles;
    include bbf-l2-forwarding-mac-learning-control;

    organization
      "Broadband Forum <https://www.broadband-forum.org>
     Common YANG Work Area";

    contact
      "Comments or questions about this Broadband Forum YANG module
     should be directed to <mailto:help@broadband-forum.org>.

     Editor:      Joey Boyd, ADTRAN

     Editor:      Ludwig Pauwels, Nokia

     PS Leader:   Joey Boyd, ADTRAN

     PS Leader:   Ken Kerpez, ASSIA

     WA Director: Joey Boyd, ADTRAN

     WA Director: Sven Ooghe, Nokia";

    description
      "This module contains a collection of YANG definitions for
     supporting the Broadband Forum requirements on layer 2 forwarding
     as applicable to access network equipment. As such, this module
     is specific to access network equipment (e.g., BBF-specified
     Access Nodes and FTTdp DPUs).

     Copyright (c) 2017-2018, Broadband Forum

     Redistribution and use in source and binary forms, with or
     without modification, are permitted provided that the following
     conditions are met:

     1. Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.

     2. Redistributions in binary form must reproduce the above
        copyright notice, this list of conditions and the following
        disclaimer in the documentation and/or other materials
        provided with the distribution.

     3. Neither the name of the copyright holder nor the names of its
        contributors may be used to endorse or promote products
        derived from this software without specific prior written
        permission.

     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
     CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,
     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

     The above license is used as a license under copyright only.
     Please reference the Forum IPR Policy for patent licensing terms
     <https://www.broadband-forum.org/ipr-policy>.

     Any moral rights which are necessary to exercise under the above
     license grant are also deemed granted under this license.

     This version of this YANG module is part of TR-383; see
     the TR itself for full legal notices.";

    revision "2018-12-03" {
      description
        "Amendment 2.
       * Approval Date:    2018-12-03.
       * Publication Date: 2018-12-03.";
      reference
        "TR-383a2: Common YANG Modules
        	<https://www.broadband-forum.org/technical/download/
        		 TR-383_Amendment-2.pdf>";

    }

    revision "2018-07-13" {
      description
        "Initial revision.
       * Approval Date:    2018-06-04.
       * Publication Date: see revision date above.";
      reference
        "TR-383: Common YANG Modules
        	<https://www.broadband-forum.org/technical/download/
        		 TR-383_Amendment-1.pdf>";

    }

    revision "2017-05-08" {
      description
        "Initial revision.
       * Approval Date:    see revision date above.
       * Publication Date: 2017-06-02.";
      reference
        "TR-383: Common YANG Modules
        	<https://www.broadband-forum.org/technical/download/
        		 TR-383.pdf>";

    }


    // features

    feature forwarder-port-groups {
      description
        "Indicates support for a grouping of forwarder ports.";
    }

    feature flooding-policies {
      description
        "Indicates support for flooding policies.";
    }

    feature flooding-policies-profiles {
      description
        "Indicates support for flooding policies profiles.";
    }

    feature forwarding-databases {
      description
        "Indicates support for forwarding databases.";
    }

    feature shared-forwarding-databases {
      description
        "Indicates support for a single forwarding database being shared
by multiple forwarders.";
    }

    feature mac-learning {
      description
        "This feature indicates whether the network element supports MAC
learning.";
    }

    feature read-system-fdb-capacity {
      description
        "Provides the system's capacity for forwarding databases, i.e.
the total number of entries for all forwarding databases
together.";
    }

    feature split-horizon-profiles {
      description
        "Indicates support for split horizon profiles.";
    }

    feature mac-learning-control-profiles {
      description
        "Indicates support for MAC address learning control profiles.";
    }

    // typedefs
    typedef forwarder-ref {
      type leafref {
        path "/bbf-l2-fwd:forwarding/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder/bbf-l2-fwd:name";
      }
      description
        "This type is used by data models that need to reference
configured forwarders.";
    }

    typedef forwarder-state-ref {
      type leafref {
        path "/bbf-l2-fwd:forwarding-state/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder/bbf-l2-fwd:name";
      }
      description
        "This type is used by data models that need to reference
operational forwarders.";
    }

    // groupings
    grouping forwarder-port {
      description
        "This grouping is use by data models that need to reference
configured forwarder ports.";
      leaf forwarder {
        type forwarder-ref;
        description
          "This leaf references a forwarder.";
      }

      leaf port {
        type leafref {
          path
            "/bbf-l2-fwd:forwarding/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder[bbf-l2-fwd:name = current()/../forwarder]/bbf-l2-fwd:ports/bbf-l2-fwd:port/bbf-l2-fwd:name";
        }
        description
          "This leaf references a port within the forwarder identified
by the leaf 'forwarder'.";
      }
    }  // grouping forwarder-port

    grouping forwarder-port-state {
      description
        "This grouping is use by data models that need to reference
operational forwarder ports.";
      leaf forwarder {
        type forwarder-state-ref;
        description
          "This leaf references a forwarder.";
      }

      leaf port {
        type leafref {
          path
            "/bbf-l2-fwd:forwarding-state/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder[bbf-l2-fwd:name = current()/../forwarder]/bbf-l2-fwd:ports/bbf-l2-fwd:port/bbf-l2-fwd:name";
        }
        description
          "This leaf references a port within the forwarder identified
by the leaf 'forwarder'.";
      }
    }  // grouping forwarder-port-state

    grouping forwarder-port-group {
      description
        "This grouping is use by data models that need to reference
configured forwarder port-groups.";
      leaf forwarder {
        type forwarder-ref;
        description
          "This leaf references a forwarder.";
      }

      leaf group {
        type leafref {
          path
            "/bbf-l2-fwd:forwarding/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder[bbf-l2-fwd:name = current()/../forwarder]/bbf-l2-fwd:port-groups/bbf-l2-fwd:port-group/bbf-l2-fwd:name";
        }
        description
          "This leaf references a port-group within the forwarder
identified by the leaf 'forwarder'.";
      }
    }  // grouping forwarder-port-group

    grouping forwarder-port-group-state {
      description
        "This grouping is use by data models that need to reference
operational forwarder port-groups.";
      leaf forwarder {
        type forwarder-state-ref;
        description
          "This leaf references a forwarder.";
      }

      leaf group {
        type leafref {
          path
            "/bbf-l2-fwd:forwarding-state/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder[bbf-l2-fwd:name = current()/../forwarder]/bbf-l2-fwd:port-groups/bbf-l2-fwd:port-group/bbf-l2-fwd:name";
        }
        description
          "This leaf references a port-group within the forwarder
identified by the leaf 'forwarder'.";
      }
    }  // grouping forwarder-port-group-state

    // objects
    container forwarding {
      description
        "Configuration nodes associated with layer 2 forwarding.";
    }  // container forwarding

    container forwarding-state {
      config false;
      description
        "State data nodes associated with layer 2 forwarding.";
    }  // container forwarding-state

    augment /bbf-l2-fwd:forwarding {
      description
        "Augment the configuration nodes associated with layer 2
forwarding with forwarder objects.";
      container forwarders {
        description
          "A forwarder is used to forward traffic between interfaces.";
        list forwarder {
          key "name";
          description
            "A list of forwarders.";
          leaf name {
            type bbf-yang:string-ascii64;
            description
              "The name of the forwarder.";
          }

          container ports {
            description
              "Configuration for ports associated with this forwarder.";
            list port {
              key "name";
              description
                "The list of ports associated with this forwarder.";
              leaf name {
                type bbf-yang:string-ascii64;
                description
                  "The name of the forwarder port.";
              }

              leaf sub-interface {
                type if:interface-ref;
                must
                  "derived-from-or-self(
/if:interfaces/if:interface[if:name = current()]
/if:type, 'bbfift:vlan-sub-interface' )" {
                  description
                    "The type of interface being referenced MUST be a
vlan-sub-interface.";
                }
                must
                  "count(/bbf-l2-fwd:forwarding
/bbf-l2-fwd:forwarders
/bbf-l2-fwd:forwarder
/bbf-l2-fwd:ports/bbf-l2-fwd:port
[bbf-l2-fwd:sub-interface = current()])< 2" {
                  description
                    "No two forwarder ports can refer to the same
sub-interface.";
                }
                description
                  "The VLAN sub-interface associated with this port.";
              }
            }  // list port
          }  // container ports

          container port-groups {
            if-feature forwarder-port-groups;
            description
              "A group of ports associated with this forwarder that
have common forwarding characteristics.";
            list port-group {
              key "name";
              description
                "A list of port groups";
              leaf name {
                type bbf-yang:string-ascii64;
                description
                  "The name of the group.";
              }

              leaf-list port {
                type leafref {
                  path
                    "../../../bbf-l2-fwd:ports/bbf-l2-fwd:port/bbf-l2-fwd:name";
                }
                description
                  "A grouping of ports associated with this forwarder.";
              }
            }  // list port-group
          }  // container port-groups
        }  // list forwarder
      }  // container forwarders
    }

    augment /bbf-l2-fwd:forwarding-state {
      description
        "Augment the state data nodes associated with layer 2
forwarding with forwarder objects.";
      container forwarders {
        description
          "A forwarder is used to forward traffic between interfaces.";
        list forwarder {
          key "name";
          description
            "A list of forwarders.";
          leaf name {
            type bbf-yang:string-ascii64;
            description
              "The name of the forwarder.";
          }

          container ports {
            description
              "Configuration for ports associated with this forwarder.";
            list port {
              key "name";
              description
                "The list of ports associated with this forwarder.";
              leaf name {
                type bbf-yang:string-ascii64;
                description
                  "The name of the forwarder port.";
              }

              leaf sub-interface {
                type if:interface-state-ref;
                must
                  "derived-from-or-self(
/if:interfaces-state/if:interface
[if:name = current()]/if:type,
'bbfift:vlan-sub-interface' )" {
                  description
                    "The type of interface being referenced must be a
VLAN sub-interface.";
                }
                description
                  "The VLAN sub-interface associated with this port.";
              }
            }  // list port
          }  // container ports
        }  // list forwarder
      }  // container forwarders
    }

    augment /bbf-l2-fwd:forwarding {
      description
        "Augment the configuration nodes associated with layer 2
forwarding with flooding policies profile objects.";
      container flooding-policies-profiles {
        if-feature flooding-policies-profiles;
        description
          "Contains a set of flooding-policies-profiles.

The flooding policies define how the system shall forward
frames in case the other forwarding mechanisms did not come
to a forwarding decision, e.g. when the destination unicast
MAC address is not available in the forwarding database.

For multicast frames this applies when there is no
corresponding entry found in the (IGMP controled) multicast
tree.

For broadcast frames this applies when there is no other
protocol specific behaviour knowledge.";
        list flooding-policies-profile {
          key "name";
          description
            "The configuration of a flooding policies profile.
One flooding policies profile can contain multiple
policies.";
          leaf name {
            type bbf-yang:string-ascii64;
            description
              "The name of a flooding policies profile.";
          }

          list flooding-policy {
            key "name";
            ordered-by user;
            description
              "A flooding-policy defines for the tuple (list of
in-interface-usages, a frame classification), if and to
which other interface usages the frame shall be flooded.

The absence of data for a particular combination results
in the default forwarding behavior to flood the frame to
all ports of the forwarder, except the one on which the
frame is received.";
            leaf name {
              type bbf-yang:string-ascii64;
              description
                "The name of a flooding policy.";
            }

            container in-interface-usages {
              description
                "Identifies the forwarder ports on which the
classification shall apply. The actual identification
is indirect: a forwarder port references a VLAN
sub-interface and this VLAN sub-interface has an
interface usage.";
              leaf-list interface-usages {
                type bbf-if-usg:interface-usage;
                description
                  "List of interface-usages to which the frame
classification applies.

An empty list means that the classification is
applied to none of the interface usages and hence
does not make sense.";
              }
            }  // container in-interface-usages

            container destination-address {
              description
                "The frame classification to be performed on the
destination MAC or IP address. Note that the MAC filter
also allows specification of unicast addresses. If used
this will apply to frames for which there was no
forwarding decision identified via other means.";
              uses bbf-classif:frame-destination-match;
            }  // container destination-address

            choice frame-forwarding {
              default "discard";
              description
                "Identifies the action to be performed on frames that
match the classification.";
              leaf discard {
                type empty;
                description
                  "The frame will be discarded.";
              }
              container out-interface-usages {
                description
                  "Identifies the forwarder ports to which the frame
shall be forwarded. The actual identification is
indirect: a forwarder port references a
VLAN sub-interface and this VLAN sub-interface has
an interface usage.";
                leaf-list interface-usages {
                  type bbf-if-usg:interface-usage;
                  description
                    "List of interface usages to which the frame shall
be forwarded.";
                }
              }  // container out-interface-usages
            }  // choice frame-forwarding
          }  // list flooding-policy
        }  // list flooding-policies-profile
      }  // container flooding-policies-profiles
    }

    augment /bbf-l2-fwd:forwarding/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder {
      description
        "Augment the forwarder configuration with configuration for
flooding policies.";
      container flooding-policies {
        if-feature flooding-policies;
        description
          "The flooding-policies define how the system shall forward
frames in case the other forwarding mechanisms did not come
to a forwarding decision.

E.g. when the destination  unicast MAC address is not
available in the forwarding database. For multicast frames
this applies when there is no corresponding entry found in
the (IGMP controled) multicast tree. For broadcast frames
this applies when there is no other protocol specific
behaviour knowledge.

The default behavior for when there is no flooding policy is
that the frame is flooded to all ports of the forwarder,
except to the port on which the frame is received. In other
words, a flooding-policy intends to restrict this flooding.";
        choice flooding-policy-type {
          description
            "Provides alternative ways to define flooding policies.";
          case profile-based {
            if-feature flooding-policies-profiles;
            leaf flooding-policies-profile {
              type leafref {
                path
                  "/bbf-l2-fwd:forwarding/bbf-l2-fwd:flooding-policies-profiles/bbf-l2-fwd:flooding-policies-profile/bbf-l2-fwd:name";
              }
              description
                "A reference to a flooding policies profile.";
            }
          }  // case profile-based
          list flooding-policy {
            key "name";
            ordered-by user;
            description
              "A flooding-policy defines for the tuple (list of
in-ports, a frame classification), if and to which
other ports the frame shall be flooded.

The absence of data for a particular combination
results in the default forwarding behavior to flood the
frame to all ports of the forwarder, except the one on
which the frame is received.";
            leaf name {
              type bbf-yang:string-ascii64;
              description
                "The name of the flooding policy.";
            }

            container in-ports {
              description
                "List of forwarder ports on which the frame
classification applies.";
              choice list-type {
                description
                  "Provides alternatives to provide a single or a set
of forwarder ports.

The absence of a leaf of this choice means that the
classification is applied to none of the ports and
hence does not make sense.";
                leaf forwarder-port {
                  type leafref {
                    path
                      "../../../../bbf-l2-fwd:ports/bbf-l2-fwd:port/bbf-l2-fwd:name";
                  }
                  description
                    "A reference to a forwarder port within this
forwarder.";
                }

                case forwarder-port-group {
                  if-feature forwarder-port-groups;
                  leaf forwarder-port-group {
                    type leafref {
                      path
                        "../../../../bbf-l2-fwd:port-groups/bbf-l2-fwd:port-group/bbf-l2-fwd:name";
                    }
                    description
                      "A reference to a forwarder port group within
this forwarder.";
                  }
                }  // case forwarder-port-group
              }  // choice list-type
            }  // container in-ports

            container destination-address {
              description
                "The frame classification to be performed on the
destination MAC or IP address. Note that the MAC
filter also allows specifation of unicast addresses.
If used this will apply to frames for which there was
no forwarding decision identified via other means.";
              uses bbf-classif:frame-destination-match;
            }  // container destination-address

            choice frame-forwarding {
              default "discard";
              description
                "Specifies how to act on matching frames.";
              leaf discard {
                type empty;
                description
                  "The frame shall be discarded.";
              }
              container out-ports {
                description
                  "List of ports to which the frame shall be
forwarded.";
                choice list-type {
                  description
                    "Specifies how to where to forward the frames.";
                  leaf forwarder-port {
                    type leafref {
                      path
                        "../../../../bbf-l2-fwd:ports/bbf-l2-fwd:port/bbf-l2-fwd:name";
                    }
                    description
                      "A reference to a forwarder port within the
same forwarder.";
                  }

                  case forwarder-port-group {
                    if-feature forwarder-port-groups;
                    leaf forwarder-port-group {
                      type leafref {
                        path
                          "../../../../bbf-l2-fwd:port-groups/bbf-l2-fwd:port-group/bbf-l2-fwd:name";
                      }
                      description
                        "A reference to a forwarder port group
within the same forwarder.";
                    }
                  }  // case forwarder-port-group
                }  // choice list-type
              }  // container out-ports
            }  // choice frame-forwarding
          }  // list flooding-policy
        }  // choice flooding-policy-type
      }  // container flooding-policies
    }

    augment /bbf-l2-fwd:forwarding {
      description
        "Augment the configuration nodes associated with layer 2
forwarding with forwarding database objects.";
      container forwarding-databases {
        if-feature forwarding-databases;
        description
          "Forwarding databases configuration.";
        list forwarding-database {
          key "name";
          description
            "The configuration of a specific forwarding database.";
          leaf name {
            type bbf-yang:string-ascii64;
            description
              "The name associated with the forwarding database.";
          }

          leaf max-number-mac-addresses {
            type uint32;
            default "4294967295";
            description
              "Limits the number of MAC addresses that can be stored in
this forwarding database.";
          }

          leaf aging-timer {
            if-feature mac-learning;
            type uint32;
            units "seconds";
            default "300";
            description
              "MAC addresses are learned in the forwarding database
against a forwarder port or against an interface. When no
incoming traffic on this forwarder port or interface is
received with a particular MAC address as source MAC
address for a period specified in this aging timer, then
this MAC address is removed from the forwarding
database.";
          }

          leaf shared-forwarding-database {
            if-feature shared-forwarding-databases;
            type boolean;
            default "false";
            description
              "If true, the forwarding database instance can be
referenced by multiple forwarder instances.

If false it can be referenced from only one forwarder
instance.";
          }

          list static-mac-address {
            key "mac-address";
            description
              "A policy for a configured MAC address specifies a
learning constraint for it. The static configuration of
MAC addresses serves multiple purposes:
- it can be configured with a rule that forbids to learn
  this MAC address
- it can be configured with a list of ports or interfaces
  on which the MAC address can be learned
- it can be statically assigned to a specific port or
  interface.
The absense of a policy for a particular MAC address
means that there is no MAC learning constraint, i.e. the
MAC address can be learned on any port or interface.";
            leaf mac-address {
              type yang:mac-address;
              description
                "The MAC address to which the constraint applies.";
            }

            choice learning-constraint {
              default
                "do-not-learn-and-discard-frame";
              description
                "Provides alternative frame processing decisions for
when the source MAC address of a frame matches the
value of the leaf mac-address.";
              leaf discard-frame {
                type empty;
                description
                  "The frame shall be discarded.";
              }

              case allowed-to-learn-on {
                if-feature mac-learning;
                choice allow-to-learn-on {
                  description
                    "The source MAC address of the frame can be learned
on any of the ports or interfaces as identified
further.";
                  container forwarder-port-ref {
                    description
                      "The reference to a forwarder port on which the
MAC address can be learned.";
                    uses forwarder-port;
                  }  // container forwarder-port-ref

                  case forwarder-port-group {
                    if-feature forwarder-port-groups;
                    container forwarder-port-group-ref {
                      description
                        "The reference to a group of forwarder ports,
the MAC address can be learned on any of these
forwarder ports.";
                      uses forwarder-port-group;
                    }  // container forwarder-port-group-ref
                  }  // case forwarder-port-group
                }  // choice allow-to-learn-on
              }  // case allowed-to-learn-on
              choice install-on {
                description
                  "The source MAC address is statically configured in
the forwarding database on a specified port or
interface.";
                case static-port {
                  description
                    "The MAC address is added statically to a
forwarder port.";
                  container static-forwarder-port-ref {
                    description
                      "The reference to a forwarder port on which the
MAC address will be statically installed and as
such affect the forwarding behavior
immediately.";
                    uses forwarder-port;
                  }  // container static-forwarder-port-ref
                }  // case static-port
              }  // choice install-on
            }  // choice learning-constraint
          }  // list static-mac-address
        }  // list forwarding-database
      }  // container forwarding-databases
    }

    augment /bbf-l2-fwd:forwarding-state {
      description
        "Augment the state data nodes associated with layer 2
forwarding with forwarding database objects.";
      container forwarding-databases {
        if-feature forwarding-databases;
        description
          "The following objects allow to read out the forwarding
database (FDB), i.e. the MAC addresses being learned within
the system.

The strategy is to offer the same flexibility as in IEEE:
 - Allows at one extreme that each VLAN has its own FDB, this
   allows the same MAC address to be learned independently
   within different VLANs.
 - Allows at the other extreme that the system has one FDB
   shared by all VLANs, this allows the same MAC address to
   be learned only once over all VLANs.
 - Allows everything in between, i.e. an FDB for a set of
   VLANs, a 2nd FDB for another set.
To support this concept it is possible to have multiple
forwarders assigned to a single FDB.";
        leaf max-number-mac-addresses {
          if-feature read-system-fdb-capacity;
          type uint32;
          description
            "Provides the system's capacity for forwarding databases,
i.e. the total number of entries for all forwarding
databases together.";
        }

        list forwarding-database {
          key "name";
          description
            "The state data of a specific forwarding database.";
          leaf name {
            type bbf-yang:string-ascii64;
            description
              "The name of the forwarding database.";
          }

          container mac-addresses {
            description
              "MAC address data in the forwarding database state.";
            list mac-address {
              key "mac-address";
              description
                "The list of MAC addresses that are stored in the
forwarding database.";
              leaf mac-address {
                type yang:mac-address;
                description
                  "A specific MAC address that is stored in the
forwarding database.";
              }

              choice learned-on {
                description
                  "In case of a shared forwarding database the MAC
address is stored on an 'Ethernet-like' interface
In case of a not-shared forwarding database the MAC
address is stored on a forwarder port of the single
forwarder that uses the forwarding database.";
                case forwarder-port {
                  description
                    "Objects used to identify a specific fowarder
port.";
                  uses forwarder-port-state;
                }  // case forwarder-port
              }  // choice learned-on
            }  // list mac-address
          }  // container mac-addresses
        }  // list forwarding-database
      }  // container forwarding-databases
    }

    augment /bbf-l2-fwd:forwarding-state/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder {
      description
        "Augment the forwarder state data to add a reference to a
forwarding database.";
      container forwarding-databases {
        if-feature forwarding-databases;
        description
          "Forwarder objects relative to forwarding databases.";
        leaf forwarding-database {
          type leafref {
            path
              "/bbf-l2-fwd:forwarding-state/bbf-l2-fwd:forwarding-databases/bbf-l2-fwd:forwarding-database/bbf-l2-fwd:name";
          }
          description
            "A reference to a forwarding database associated with a
forwarder.";
        }
      }  // container forwarding-databases
    }

    augment /bbf-l2-fwd:forwarding/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder {
      description
        "Augment the forwarder configuration with MAC address
management.";
      container mac-learning {
        if-feature forwarding-databases;
        description
          "The forwarding decision for each frame shall result in an
unambiguous decision on the outgoing forwarder port(s). This
combined with the dynamic behavior of MAC address learning
results in the need for a unique learning decision or static
configuration of MAC addresses.

In case the same source MAC address is used on multiple
interfaces, then various strategies can be applied:
- learn the MAC address the first time it is used, and at the
  occasion of a second attempt, do not move the MAC address
  from the first forwarder port to another, instead generate
  an alarm for attempts of an undesired MAC movement.
- learn/move the MAC address on/to the forwarder port where
  it is used the last time.
- perform MAC address translation into a unique MAC address.
This strategy is also port specific: e.g. in case a MAC
address is learned on a user port, then it might be forbidden
to move it to another user port, while it is acceptable to
move it to the network port.";
        leaf forwarding-database {
          type leafref {
            path
              "/bbf-l2-fwd:forwarding/bbf-l2-fwd:forwarding-databases/bbf-l2-fwd:forwarding-database/bbf-l2-fwd:name";
          }
          description
            "A reference to a forwarding database.

The absence of a reference to a forwarding datase
automatically means that MAC addresses are not learned.";
        }
      }  // container mac-learning
    }

    augment /if:interfaces/if:interface {
      when
        "derived-from-or-self(if:type, 'ianaift:ethernetCsmacd') or
derived-from-or-self(if:type, 'ianaift:ieee8023adLag') or
derived-from-or-self(if:type, 'ianaift:ptm') or
derived-from-or-self(if:type, 'bbfift:vlan-sub-interface') or
derived-from(if:type, 'bbfift:ethernet-like')" {
        description
          "Ethernet / Ethernet-like interfaces on which MAC address are
learned can have a maximum number for what can be learned for
the full interface. MAC addresses are typically learned in
the scope of a VLAN. Therefore it is also possible to
restrict the number of MAC addresses that can be learned per
VLAN per Ethernet (-like) interface.";
      }
      if-feature forwarding-databases and mac-learning;
      description
        "Augment the interface list with MAC learning configuration.";
      container mac-learning {
        description
          "Data nodes for MAC learning configuration.";
        leaf max-number-mac-addresses {
          type uint32;
          default "4294967295";
          description
            "The maximum number of MAC addresses that can be stored in
the forwarding database for this interface.";
        }

        leaf number-committed-mac-addresses {
          type uint32;
          default "1";
          description
            "The number of MAC addresses for which resources are
reserved in the forwarding database. In this way the system
guarantees that for this interface it will always be able
to support that amount of MAC addresses.";
        }

        leaf mac-learning-enable {
          type boolean;
          default "true";
          description
            "Enabling MAC learning means that the MAC address will be
learned from the source MAC address from frames received
over this interface. MAC learning disabled means that the
MAC address will not be learned from the source MAC address
from frames received over this interface. For example this
allows to provide a 1:1 VLAN without any MAC learning from
frames forwarded within it.

MAC learning will be executed in case mac-learning-enable
is 'true' on the VLAN sub-interface or on the lower-layer
interface that supports the object (dependent on using
independent or a shared forwarding database).";
        }

        leaf mac-learning-failure-action {
          type enumeration {
            enum "forward" {
              value 0;
              description
                "The frame is forwarded despite the source MAC address
can not be learned.";
              reference
                "IEEE - 802.1Q-2014, Table 8-7";

            }
            enum "discard" {
              value 1;
              description
                "The frame from which the source MAC address could not
be learned is discarded.";
              reference
                "TR-101i2 - R114, R115";

            }
          }
          default "forward";
          description
            "When the MAC learning from the source MAC address of a
frame is not possible because for example the maximum
number of MAC addresses that can be learned on the
interface is reached, or for example the forwarding
database is full, then the system's behavior is as
configured with this leaf.

Normal IEEE behavior is to forward the frame without MAC
learning. BBF expected behavior is to discard the frame.";
        }
      }  // container mac-learning
    }

    augment /bbf-l2-fwd:forwarding {
      description
        "Augment the configuration nodes associated with layer 2
forwarding with split horizon profile objects.";
      container split-horizon-profiles {
        if-feature split-horizon-profiles;
        description
          "Split horizon profile configuration.";
        list split-horizon-profile {
          key "name";
          description
            "A profile manages (not) allowed forwarding between various
forwarder ports based on their underlying interface usage.
The absence of data for a particular in-interface-usage has
a result that from that type of forwarder ports frames are
allowed to be forwarded to any other forwarder port.";
          leaf name {
            type bbf-yang:string-ascii64;
            description
              "The name of the profile.";
          }

          list split-horizon {
            key "in-interface-usage";
            description
              "Frame forwarding is not allowed from interfaces/ports
that have an interface usage as specified in
in-interface-usage to interfaces/ports that have an
interface usage for which the value is in the leaf-list
out-interface-usages.";
            leaf in-interface-usage {
              type bbf-if-usg:interface-usage;
              description
                "The interface usage from which forwarding is specified
here.";
            }

            leaf-list out-interface-usage {
              type bbf-if-usg:interface-usage;
              description
                "The interface usage to which frames coming from the
'in-interface-usage' are not allowed to be forwarded.
Frame forwarding to interface usages not configured is
allowed.";
            }
          }  // list split-horizon
        }  // list split-horizon-profile
      }  // container split-horizon-profiles
    }

    augment /bbf-l2-fwd:forwarding/bbf-l2-fwd:forwarders/bbf-l2-fwd:forwarder {
      description
        "Augment the forwarder configuration to add a reference to a
split horizon profile.";
      container split-horizon-profiles {
        if-feature split-horizon-profiles;
        description
          "A split-horizon-profile allows to restrict forwarding between
its forwarder ports based on their interface usages.

Without split-horizon-profile, packets can be forwarded
within a forwarder from any of its forwarder ports to any
other of its forwarder ports.";
        leaf split-horizon-profile {
          type leafref {
            path
              "/bbf-l2-fwd:forwarding/bbf-l2-fwd:split-horizon-profiles/bbf-l2-fwd:split-horizon-profile/bbf-l2-fwd:name";
          }
          description
            "A reference to a split horizon profile associated with a
forwarder.";
        }
      }  // container split-horizon-profiles
    }

    augment /bbf-l2-fwd:forwarding {
      description
        "Augment the configuration nodes associated with layer 2
forwarding with MAC address learning control profile objects.";
      container mac-learning-control-profiles {
        if-feature forwarding-databases and mac-learning and
mac-learning-control-profiles;
        description
          "Contains a set of MAC address learning control profiles.";
        list mac-learning-control-profile {
          key "name";
          description
            "The configuration of a MAC address learning control
profile.

A profile controls the MAC address learning behavior that
deviates from the default MAC learning in an IEEE bridge,
i.e. that behavior that deviates from 'learn on the last
port or interface on which a frame with the corresponding
source MAC address is received'. This implies that the
default behavior is that the MAC address is always learned
and that MAC movement is allowed from any port or interface
to any other port or interface, except if this would be in
conflict with static MAC address configuration.";
          leaf name {
            type bbf-yang:string-ascii64;
            description
              "The name of a MAC address learning control profile.";
          }

          list mac-learning-rule {
            key "receiving-interface-usage";
            description
              "Defines what to do when a frame is received with a
particular source MAC address and this MAC address is not
yet stored on that port or interface.";
            leaf receiving-interface-usage {
              type bbf-if-usg:interface-usage;
              description
                "Defines MAC address learning rules for frames received
on a port for which the interface usage of the
underlying interface is of this value.";
            }

            choice mac-learning-action {
              description
                "Specifies how to learn a MAC address on a port or
interface that has a usage specified by the leaf
receiving-interface-usage.";
              case learn-and-translate {
                description
                  "In case this is not in conflict with static MAC
address configuration, then the (source) MAC address
will be learned on the port or interface where the
frame is received, and the system will perform
(source) MAC address translation before forwarding
the frame.";
                reference
                  "TR-101i2: Migration to Ethernet-Based DSL Aggregation
                  R-111";

              }  // case learn-and-translate

              case learn-but-do-not-move {
                description
                  "In case the source MAC address is not known in the
forwarding database on any other port or interface,
and in case a possible learning is not in conflict
with any static MAC address configuration
then it is learned on the port or interface on which
the frame is received (in case other criteria such as
specified by the leaf max-number-mac-addresses
allow).

In case the MAC address was already known in the
forwarding database, where it was associated to a
port or interface, and a possible learning is not in
conflict with any static MAC address configuration
then MAC movement is restricted:
the MAC address can not move and the frame will be
discarded in case the interface usage of the port or
interface where the frame is received is part of the
leaf-list mac-can-not-move-to of the list entry
identified by the interface usage of the port or
interface where the MAC address was already
associated to. The MAC address can move in case the
interface usage of the port or interface where the
frame is received is not part of this list.";
                reference
                  "TR-101i2: Migration to Ethernet-Based DSL Aggregation
                  R-112 and R-113";

                leaf-list mac-can-not-move-to {
                  type bbf-if-usg:interface-usage;
                  description
                    "Provides a list of interface-usage values to which
MAC addresses can not move.";
                }
              }  // case learn-but-do-not-move
            }  // choice mac-learning-action
          }  // list mac-learning-rule
        }  // list mac-learning-control-profile
      }  // container mac-learning-control-profiles
    }

    augment /bbf-l2-fwd:forwarding/bbf-l2-fwd:forwarding-databases/bbf-l2-fwd:forwarding-database {
      if-feature forwarding-databases;
      description
        "Augment the forwarder configuration with configuration for MAC
address learning control.";
      container mac-learning-control {
        if-feature mac-learning and mac-learning-control-profiles;
        description
          "The MAC learning control defines how the system shall act
when a frame is received for which the source MAC address was
not learned before on the port or interface where the frame
is received.";
        leaf mac-learning-control-profile {
          type leafref {
            path
              "/bbf-l2-fwd:forwarding/bbf-l2-fwd:mac-learning-control-profiles/bbf-l2-fwd:mac-learning-control-profile/bbf-l2-fwd:name";
          }
          description
            "A reference to a MAC address learning control profile.";
        }

        leaf generate-mac-learning-alarm {
          type boolean;
          default "false";
          description
            "If true, an alarm shall be generated on an attempt of a not
allowed MAC movement. Allowed / not allowed MAC movements
are controlled via the referenced entry in the list
mac-learning-control-profile.";
        }
      }  // container mac-learning-control
    }
  }  // module bbf-l2-forwarding