submodule infix-if-container {
  yang-version 1.1;
  belongs-to infix-interfaces {
    prefix infix-if;
  }

  import ietf-inet-types {
    prefix inet;
  }
  import ietf-interfaces {
    prefix if;
  }
  import ietf-ip {
    prefix ip;
  }

  organization "KernelKit";
  contact      "kernelkit@googlegroups.com";
  description  "Container network to interface mapping for ietf-interfaces.
                Ensures a container interface can never be a bridge port, or
                LAG member, at the same time.";

  revision 2024-11-15 {
    description "Two changes:
                   - Relocate 'feature containers' declaration to here
                   - Fix pyang linter errors and warnings, dropping unused
                     imports and dropping the default value for subnet";
    reference "internal";
  }
  revision 2024-10-29 {
    description "Add read only container list to container-network";
    reference "internal";
  }
  revision 2024-01-15 {
    description "Initial revision.";
    reference "internal";
  }

  /*
   * Features
   */

  feature containers {
    description "Containers is an optional build-time feature in Infix.";
  }

  /*
   * Identities
   */

  identity container-network {
    description "Container network type";
  }

  identity bridge {
   base container-network;
    description "Container bridge with IP masquerading, portmappping, and firewalling.";
  }

  identity host {
    base container-network;
    description "Host device, e.g., one end of a VETH pair or other host interface.";
  }

  /*
   * Data Nodes
   */

  augment "/if:interfaces/if:interface/infix-if:port" {
    description "Augments the interface model with container networks.";
    if-feature containers;

    case container-network {
      container container-network {
	presence "Container network mapping.";

	leaf type {
	  description "Masquerading container bridge or a host interface";
	  type identityref {
	    base container-network;
	  }
	}
         leaf-list containers {
                 type string;
                 config false;
                 description "List of containers using this interface";
         }
	list subnet {
	  description "Static IP ranges to hand out addresses to containers from.

                       If no subnet is provided, a default 172.17.0.0/16 one is
                       set up.  This is the default in a standard Docker setup.

                       A container bridge forwards DNS, NTP, and SSH by default to
                       the host interfaces.";
	  when "../type = 'infix-if:bridge'";
	  key subnet;

	  leaf subnet {
	    type inet:ip-prefix;
	    description "Subnet to assign addresses from, round-robin assignment.";
	  }

	  leaf gateway {
	    type inet:ip-address;
	    description "Optional gateway address for the subnet, defaults to .1.

	                 This will be used as the address of the container bridge.";
	  }
	}

	list route {
	  description "IPv4 or IPv6 routes to be added to container.

                       For bridge type interfaces the gateway can be omitted, the
                       IP address of the container bridge will then be used as the
                       next-hop address.";
	  key subnet;

	  leaf subnet {
	    type inet:ip-prefix;
	    description "Destination (subnet) IP address.";
	  }

	  leaf gateway {
	    type inet:ip-address;
	    description "Optional gateway (next-hop) IP address for the route.";
	  }
	}

	must "count(route) = 0 or count(../ip:ipv4/ip:address) or count(../ip:ipv6/ip:address)" {
	  error-message "Static routes only allowed if a static IP address is set.";
	}
      }
    }
  }
}
