On 4 August 2014 09:53, Sergey Popovich <popovich_sergei@mail.ru> wrote:

> Hi,

Hello.

> The problem I am facing is that when I adjust a filter in order to
> withdraw the route, all routes are withdrawn and the remaining are
> announced again. According to the doc if a reload on bird brings a new
> configuration for a protocol, that protocol will be restarted. So, it is
> expected behavior.
>

You have changed import filter of direct1 protocol, thus direct1 gets
reconfigured (on HUP or birdc configure). However this protocol does not
perform "soft" reconfiguration on filter changes thus direct1 restarts
unconditionally to apply your filter changes (IP removal/addition).

All routes flushed out from the table (causing BGP withdrawal) and
fetched from the protocol (direct) again to the table (causing BGP update).

This seems normal behavior.



Sergey, thanks you very much for this very detailed explanation.


You could simply attach your loopback_ACL filter to the BGP_PEERS template
export (which any needed adjustments, or just make loopback_ACL to work as
function returning false/true and use it in anycast_range) to solve your case.

Also I suggest you to use global prefix set definition, as local variable
(in filter/function) is created/assigned each time function is called.

For example:
------------

# It is probably good idea to have such protocol configred in most cases.
# It fetches list of the interfaces in system and provides them to the other
# protocols (except OSPF, it has it's own mechanisms).
#
protocol device {
  scan time 10;
}

# This set should be modified only when new frontend subnet is added.
# direct1 would restart on protocol filter change.
#
define ACAST_PS_DIRECT1 =
  [
    192.168.200.0/24{32,32}
  ];

protocol direct {
  # Import directly connected routes from "lo" interface.
  interface "lo";

  # This may  be is needed to properly resolve nexthops from upstream routes.
  interface "<interface_to_your_routers>";


what do you mean by this ?

Since I only want to export routes for IPs in the loopback interface, I thought I can safely skip other interfaces for
protocol direct. Well, with the filters in place, I don't worry for accidentally announcing routes that I shouldn't.
Furthermore, as a safeguard I have set the upstream routers  to allow announcements only for the specific prefix(192.168.200.0/24). Oh yes I play very safe here:-)

 
  # Do not import from other sources.
  interface "-*";

  # Import only allowed IPs from the "lo" and route from the upstream
  # interface.
  import where net ~ ACAST_PS_DIRECT1 || ifname
="<interface_to_your_routers>";


I don't need to import anything. Bird is used only as an advertisement system.

 
  # No export to the protocol, not necessary
  export none;
}

# This is global constant for your prefix set (PS) 192.168.200.0/24.
#
# Place this definition into external file and source it with include
# directive from the global configuration file if you wish to modify
# this PS from the outside (e.g. by some HA script).
#
define ACAST_PS_ADVERTISE =
  [
    192.168.200.1/32,  # Frontend 1
    192.168.200.2/32   # Frontend 2
  ];

function acast_advertise()
{
  return net ~ ACAST_PS_ADVERTISE;
}

filter anycast_range
{
  if acase_advertise() then
    accept;
  reject;
}

Tested similar config with BIRD 1.3.11 and seems no unwanted
withdrawals spot.




I configured bird as you suggested[1] and after a restart I removed 192.168.200.1/32 from the prefix set[2]

See below the log

13:29:18 <INFO> Reconfiguration requested by SIGHUP
13:29:18 <INFO> Reconfiguring
13:29:18 <TRACE> direct1: Reconfigured
13:29:18 <TRACE> bgp_peer1: Reconfigured
13:29:18 <INFO> Reloading protocol bgp_peer1
13:29:18 <TRACE> bgp_peer1: State changed to feed
13:29:18 <TRACE> bgp_peer2: Reconfigured
13:29:18 <INFO> Reloading protocol bgp_peer2
13:29:18 <TRACE> bgp_peer2: State changed to feed
13:29:18 <INFO> Reconfigured
13:29:18 <TRACE> bgp_peer1 < filtered out 192.168.200.1/32 dev lo
13:29:18 <TRACE> bgp_peer1 < removed 192.168.200.1/32 dev lo
13:29:18 <TRACE> bgp_peer1 < replaced 192.168.200.2/32 dev lo
13:29:18 <TRACE> bgp_peer1: State changed to up
13:29:18 <TRACE> bgp_peer2 < filtered out 192.168.200.1/32 dev lo
13:29:18 <TRACE> bgp_peer2 < removed 192.168.200.1/32 dev lo
13:29:18 <TRACE> bgp_peer2 < replaced 192.168.200.2/32 dev lo
13:29:18 <TRACE> bgp_peer2: State changed to up


what the meaning of the 'replaced' here?
 
and the output of birdcl show protocols all \"bgp*\" in  a loop

### Mon Aug 4 13:29:11 CEST 2014 ###
  Routes:         0 imported, 2 exported, 0 preferred
    Import updates:              0          0          0          0          0
    Import withdraws:            0          0        ---          0          0
    Export updates:              2          0          0        ---          2
    Export withdraws:            0        ---        ---        ---          0
  Routes:         0 imported, 2 exported, 0 preferred
    Import updates:              0          0          0          0          0
    Import withdraws:            0          0        ---          0          0
    Export updates:              2          0          0        ---          2
    Export withdraws:            0        ---        ---        ---          0
### Mon Aug 4 13:29:16 CEST 2014 ###
  Routes:         0 imported, 1 exported, 0 preferred
    Import updates:              0          0          0          0          0
    Import withdraws:            0          0        ---          0          0
    Export updates:              4          0          1        ---          3
    Export withdraws:            0        ---        ---        ---          1
  Routes:         0 imported, 1 exported, 0 preferred
    Import updates:              0          0          0          0          0
    Import withdraws:            0          0        ---          0          0
    Export updates:              4          0          1        ---          3
    Export withdraws:            0        ---        ---        ---          1
### Mon Aug 4 13:29:21 CEST 2014 ###


Thank you very much for taking the time to provide a complete solution for me. It is very much appreciated.

Cheers,
Pavlos

[1] bird.conf

include "/etc/bird.d/anycast_prefixes.conf";

define ACAST_PS_DIRECT1 = [ 192.168.200.0/24{32,32} ];

function anycast_advertise()
{
    return net ~ ACAST_PS_ADVERTISE;
}

filter anycast_range {
    if anycast_advertise() then
        accept;

    reject;
}

router id 192.168.88.194;
listen bgp address 192.168.88.194;

protocol direct {
    interface "lo";
        debug all;
        import where net ~ ACAST_PS_DIRECT1;
        export none;
}

protocol kernel kernel1 {
    disabled yes;
}

protocol device {
    scan time 10;
}

protocol static {
    disabled yes;
}

protocol bfd {
    interface "eth0" {
        min rx interval 500 ms;
        min tx interval 500 ms;
        idle tx interval 1000 ms;
        multiplier 3;
    };
}

template bgp BGP_PEERS {
    bfd on;
    debug all;
    import none;
    export filter anycast_range;
    direct;
    hold time 30;
    startup hold time 240;
    connect retry time 120;
    keepalive time 10;
    start delay time 5;
    error wait time 60, 300;
    error forget time 300;
    disable after error off;
    next hop self;
    path metric 1;
    default bgp_med 0;
    default bgp_local_pref 0;
}

protocol bgp bgp_peer1 from BGP_PEERS {
    disabled no;
    description "My-BGP-Peer1";
    local as 46111;
    neighbor 192.168.95.252 as 46111;
    source address 192.168.88.194;
}

protocol bgp bgp_peer2 from BGP_PEERS {
    disabled no;
    description "My-BGP-Peer2";
    local as 46111;
    neighbor 192.168.95.253 as 46111;
    source address 192.168.88.194;
}


[2] /etc/bird.d/anycast_prefixes.conf
define ACAST_PS_ADVERTISE =
    [
        192.168.200.1/32,  # Frontend 1
        192.168.200.2/32  # Frontend 2
    ];