log "/var/log/bird.log" all; debug protocols all;

# The Device protocol is not a real routing protocol. It does not generate any
# routes and it only serves as a module for getting information about network
# interfaces from the kernel. It is necessary in almost any configuration.
protocol device {
}

# The direct protocol is not a real routing protocol. It automatically generates
# direct routes to all network interfaces. Can exist in as many instances as you
# wish if you want to populate multiple routing tables with direct routes.
protocol direct {
 ipv4;     # Connect to default IPv4 table
 # ipv6;   # ... and to default IPv6 table
}

# The Kernel protocol is not a real routing protocol. Instead of communicating
# with other routers in the network, it performs synchronization of BIRD
# routing tables with the OS kernel. One instance per table.
protocol kernel {
        ipv4 {                # Connect protocol to IPv4 table by channel
          # table master4;    # Default IPv4 table is master4
          # import all;       # Import to table, default is import all
          export all;         # Export to protocol. default is export none
        };
        # learn;                  # Learn alien routes from the kernel
        # kernel table 10;        # Kernel table to synchronize with (default: main)
}

# Another instance for IPv6, skipping default options
# protocol kernel {
#   ipv6 { export all; };
# }

# Static routes (Again, there can be multiple instances, for different address
# families and to disable/enable various groups of static routes on the fly).
protocol static {
  ipv4;                   # Again, IPv4 channel with default options

  # route 0.0.0.0/0 via 198.51.100.10;
  # route 192.0.2.0/24 blackhole;
  # route 10.0.0.0/8 unreachable;
  # route 10.2.0.0/24 via "eth0";
  # # Static routes can be defined with optional attributes
  # route 10.1.1.0/24 via 198.51.100.3 { rip_metric = 3; };
  # route 10.1.2.0/24 via 198.51.100.3 { ospf_metric1 = 100; };
  # route 10.1.3.0/24 via 198.51.100.4 { ospf_metric2 = 100; };
}

# Pipe protocol connects two routing tables. Beware of loops.
# protocol pipe {
#       table master4;          # No ipv4/ipv6 channel definition like in other protocols
#       peer table mrib4;
#       import all;             # Direction peer table -> table
#       export all;             # Direction table -> peer table
# }

# RIP example, both RIP and RIPng are supported
# protocol rip {
#       ipv4 {
#               # Export direct, static routes and ones from RIP itself
#               import all;
#               export where source ~ [ RTS_DEVICE, RTS_STATIC, RTS_RIP ];
#       };
#       interface "eth*" {
#               update time 10;                 # Default period is 30
#               timeout time 60;                # Default timeout is 180
#               authentication cryptographic;   # No authentication by default
#               password "hello" { algorithm hmac sha256; }; # Default is MD5
#       };
# }

# OSPF example, both OSPFv2 and OSPFv3 are supported
# protocol ospf v3 {
#       ipv6 {
#               import all;
#               export where source = RTS_STATIC;
#       };
#       area 0 {
#               interface "eth*" {
#                       type broadcast;         # Detected by default
#                       cost 10;                # Interface metric
#                       hello 5;                # Default hello perid 10 is too long
#               };
#               interface "tun*" {
#                       type ptp;               # PtP mode, avoids DR selection
#                       cost 100;               # Interface metric
#                       hello 5;                # Default hello perid 10 is too long
#               };
#               interface "dummy0" {
#                       stub;                   # Stub interface, just propagate it
#               };
#       };
#}

# Define simple filter as an example for BGP import filter
# See https://gitlab.labs.nic.cz/labs/bird/wikis/BGP_filtering for more examples
# filter rt_import
# {
#       if bgp_path.first != 64496 then accept;
#       if bgp_path.len > 64 then accept;
#       if bgp_next_hop != from then accept;
#       reject;
# }

function is_valid_network() {
  return net ~ [
    141.80.181.40/32 # guix.gnu.org
  ];
}

function announce() {
  return net ~ [
    192.168.154.0/24
  ];
}

# BGP example, explicit name 'uplink1' is used instead of default 'bgp1'
# protocol bgp uplink1 {
#   strict bind;
#   description "My BGP uplink";
#   local 192.168.25.3 as 64514;
#   neighbor 192.168.25.2 as 64513;
#   ipv4 {
#     import filter {
#       if is_valid_network()
#       then {
#         accept;
#       }
#       else {
#         reject;
#       }
#     };
#     export filter {
#       if announce()
#       then {
#         accept;
#       }
#       else {
#         reject;
#       }
#     };
#   };
# }

# Template example. Using templates to define IBGP route reflector clients.
# template bgp rr_clients {
#       local 10.0.0.1 as 65000;
#       neighbor as 65000;
#       rr client;
#       rr cluster id 1.0.0.1;
#
#       ipv4 {
#               import all;
#               export where source = RTS_BGP;
#       };
#
#       ipv6 {
#               import all;
#               export where source = RTS_BGP;
#       };
# }
#
# protocol bgp client1 from rr_clients {
#       neighbor 10.0.1.1;
# }
#
# protocol bgp client2 from rr_clients {
#       neighbor 10.0.2.1;
# }
#
# protocol bgp client3 from rr_clients {
#       neighbor 10.0.3.1;
# }

define OWNAS = 64512;

template bgp dnpeers {
    local as OWNAS;
    path metric 1;

    ipv4 {
        next hop self;
        # import filter {
        #   if is_valid_network() && !is_self_net() then {
        #     if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
        #       print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
        #       reject;
        #     } else accept;
        #   } else reject;
        # };

        # import filter {
        #   if !is_self_net() then {
        #     accept;
        #   } else reject;
        # };

        # export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; };
        # export filter {  };

        export filter { accept; };
        import limit 1000 action block;
    };
}

include "/etc/bird/peers/*";