{ config, lib, pkgs, ... }: with lib; let cfg = config.nix-nos.bgp; # BGP peer type peerType = types.submodule { options = { address = mkOption { type = types.str; description = "Peer IP address"; example = "192.168.1.1"; }; asn = mkOption { type = types.int; description = "Peer AS number"; example = 65001; }; description = mkOption { type = types.str; default = ""; description = "Human-readable peer description"; }; }; }; # BGP announcement type announcementType = types.submodule { options = { prefix = mkOption { type = types.str; description = "IP prefix to announce in CIDR notation"; example = "10.0.0.0/24"; }; nexthop = mkOption { type = types.nullOr types.str; default = null; description = "Override next-hop IP address"; }; }; }; in { imports = [ ./bird.nix ./gobgp.nix ]; options.nix-nos.bgp = { enable = mkEnableOption "BGP routing"; backend = mkOption { type = types.enum [ "bird" "gobgp" ]; default = "bird"; description = "BGP daemon backend to use"; }; asn = mkOption { type = types.int; description = "Local AS number"; example = 64512; }; routerId = mkOption { type = types.str; description = "BGP router ID (typically an IP address)"; example = "10.0.0.1"; }; peers = mkOption { type = types.listOf peerType; default = []; description = "BGP peer configurations"; }; announcements = mkOption { type = types.listOf announcementType; default = []; description = "Prefixes to announce to BGP peers"; }; }; config = mkIf (config.nix-nos.enable && cfg.enable) { # Assertions assertions = [ { assertion = cfg.asn > 0 && cfg.asn < 4294967296; message = "BGP ASN must be between 1 and 4294967295"; } { assertion = cfg.routerId != ""; message = "BGP router ID must be configured"; } ]; # Backend-specific configuration is handled by bird.nix and gobgp.nix }; }