Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Writes all functions in all files. #8

Closed
Bjorn-H opened this issue Apr 19, 2022 · 16 comments
Closed

Writes all functions in all files. #8

Bjorn-H opened this issue Apr 19, 2022 · 16 comments

Comments

@Bjorn-H
Copy link

Bjorn-H commented Apr 19, 2022

When configuring multiple files when using multiple functions it will write all function in all files.

[ipv4]
enable = true
configfile = "/etc/bird.d/birdwatcher-ipv4.conf"
reloadcommand = "/usr/sbin/birdc configure"

[ipv6]
enable = true
configfile = "/etc/bird.d/birdwatcher-ipv6.conf"
reloadcommand = "/usr/sbin/birdc configure"


  [services."ipv4"]
    command = "/path/to/script_v4.sh"
    prefixes = [ '127.0.2.1/32','127.0.2.2/32' ]
    functionname = "ipv4"
    interval = 5
    timeout = 10
    fail = 2
    rise = 2

  [services."ipv6"]
    command = "/path/to/script_v6.sh"
    prefixes = [ '2001::1/128','2001::2/128' ]
    functionname = "ipv6"
    interval = 5
    timeout = 10
    fail = 2
    rise = 2

cat /etc/bird.d/birdwatcher-ipv4.conf

# DO NOT EDIT MANUALLY
function ipv4()
{
        return net ~ [
                127.0.2.1/32,
                127.0.2.2/32
        ];
}
function ipv6()
{
        return false;
}

cat /etc/bird.d/birdwatcher-ipv6.conf

# DO NOT EDIT MANUALLY
function ipv4()
{
        return false;
}
function ipv6()
{
        return net ~ [
                2001::1/128,
                2001::2/128
        ];
}

This causes the filtering for ipv4 to become false all the time and no exported prefixes.
And if I set the configuration file to the same only the ipv6 is filled up, ipv4 is never set.

birdwatcher -version
birdwatcher, build 18df0fd (master branch)

@skoef
Copy link
Owner

skoef commented Apr 19, 2022

Thanks for filing this issue! Just for my understanding: since you have a separate config file for ipv4 and ipv6 for birdwatcher to manage, may I assume you include the first config file in bird and the latter in bird6 config? And if so, why does it matter that your ipv4 ranges are not exported in bird6 and vice versa?

@Bjorn-H
Copy link
Author

Bjorn-H commented Apr 19, 2022

Hi,

I am running BIRD 2.0.9 from EPEL.
Since we are running BIRD v2 there is not two different configurations for v4 and v6 anymore, just different sections.

@Bjorn-H
Copy link
Author

Bjorn-H commented Apr 19, 2022

These are our configs.

bird.conf

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

log syslog all;

include "/etc/bird.d/*.filter";

include "/etc/bird.d/*.bfd";
include "/etc/bird.d/*.bgp";

protocol direct {
  interface "anycast";
}

protocol device {
  scan time 5;
}

protocol kernel {
  ipv4 { export all; };
  kernel table 10;
  learn;
}

protocol kernel {
  ipv6 { export all; };
  kernel table 10;
  learn;
}


in bird.d directory we have these files:

anycast4.bgp
anycast4.filter
anycast4.kernel
anycast4-primary-backup.conf
anycast6.bgp
anycast6.filter
anycast6.kernel
anycast6-primary-backup.conf
anycast.bfd
birdwatcher-ipv4.conf
birdwatcher-ipv6.conf

BGP:

protocol bgp Anycast {
  description "Anycast IPv4";
  local <ip> as <local_as>;
  neighbor <gw> as <remote_as>;
  hold time 90;

  ipv4 {
    import none;
    export filter export_to_bgp4;
  };

  graceful restart on;
  # bfd;
}

Filter:

filter export_to_bgp4 {
  if net ~ LOCALPREF4_200 && ipv4() then {
    bgp_community.add((<AS>, 200));
    accept;
  } else if net ~ LOCALPREF4_100 && ipv4() then {
    bgp_community.add((<AS>, 100));
    accept;
  } else if ipv4() then {
    bgp_community.add((<AS>, 50));
    accept;
  }
  reject;
}

The files for IPv4 and IPv6 are the same, main difference is the number 4 and 6 to make a difference between them.

@skoef
Copy link
Owner

skoef commented Apr 19, 2022

I may have made birdwatcher a bit too specific for BIRD 1.x which is what I still tend to use most. Ideally, when using BIRD 2, you should be able to define the same config file for both protocols, right?

@Bjorn-H
Copy link
Author

Bjorn-H commented Apr 19, 2022

Yes, if a single file can be used it will be enough. As long the function name is configured unique.

(I read your comment a bit to fast and misread it, this since I was stressed between meetings at work)

@skoef
Copy link
Owner

skoef commented Apr 20, 2022

@Bjorn-H I ended up removing all IP-family specific separation in a branch called bird2. Could you check this out and let me know if that works for you? 👍

@Bjorn-H
Copy link
Author

Bjorn-H commented Apr 25, 2022

Sorry I have not had the time to test this before today.

I get these errors:

birdwatcher[9963]: level=warning msg="error updating configuration" error="open /etc/bird/birdwatcher.conf.tmp: no such file or directory" file=/etc/bird/birdwatcher.conf
birdwatcher[9963]: level=error msg="could not apply BIRD config" error="open /etc/bird/birdwatcher.conf.tmp: no such file or directory"

@Bjorn-H
Copy link
Author

Bjorn-H commented Apr 25, 2022

It seems that it does not read the global statement:

[global]
    configfile = "/etc/bird.d/birdwatcher.conf"
    reloadcommand = "/usr/sbin/birdc configure"

Since is is trying to read the:

file=/etc/bird/birdwatcher.conf

It is not super clear, but I have defined the directory as '/etc/bird.d' and it is trying to work in the directory '/etc/bird'

@Bjorn-H
Copy link
Author

Bjorn-H commented Apr 25, 2022

creating the '/etc/bird' directory, it seems to create the files properly and the output seems fine as well.

@skoef
Copy link
Owner

skoef commented Apr 25, 2022

Perhaps that is not clear, but you shouldn't add the [global] level in the configuration, your config should just read:

configfile = "/etc/bird.d/birdwatcher.conf"
reloadcommand = "/usr/sbin/birdc configure"

[services]
  ...

@Bjorn-H
Copy link
Author

Bjorn-H commented Apr 26, 2022

Ok, making those changes, it works as it should.

One thing, you should add a Makefile, so it will be easily compiled and can easily be used when creating RPM's.

It such a big difference in system load after switching from anycast-healthchecker to birdwatcher.

@skoef
Copy link
Owner

skoef commented Apr 26, 2022

The other day I added goreleaser config that creates DEB packages as well as the binary itself, so it is easily downloadable from the releases page. I have no RHEL/CentOS/whatever system to my disposal so I can't test whether an RPM package works though.

I'm glad you like the performance of birdwatcher, that was ultimately what made me write it in the first place! 👍

@Bjorn-H
Copy link
Author

Bjorn-H commented Apr 28, 2022

I am no go-lang person and have little experience with the universe around it. But if goreleaser is as easy as Makefiles, then it should not be a problem for us to create our flavored RPM's in our build environment.

If the same functionality that you have in birdwatcher is written in python I think that it would have performed satisfactorily as well. anycast-healthchecker have some design flaws that creates this issue. Especially when you want to announce 50+ prefixes.

Our load went down from more than 10 to around 1-2. (And that is when the service is active which take around that load normally)

We will roll out birdwatcher into production next week. Hopefully this will fix the issues, and i highly presume it will, we have been monitoring using anycast-healthchecker.

@skoef
Copy link
Owner

skoef commented Apr 28, 2022

@Bjorn-H could you try this RPM package: https://github.com/skoef/birdwatcher/releases/tag/v1.0.0-beta1

@Bjorn-H
Copy link
Author

Bjorn-H commented May 9, 2022

Hi, we have already starting to use our compilation in production.

Also we prefer to compile the stuff in our environment since we have had previous problem with pre-compiled RPM's.

I did a simple manual check of the package and one thing that I personally would change is that since it is a daemon it should follow the standard and be installed in sbin and not bin.

@skoef
Copy link
Owner

skoef commented May 9, 2022

You're right, that is better. Goreleaser installs it in /usr/bin by default, changed it to /usr/sbin. I'll wrap up some other things soon and will release a proper v1.0.0. Thanks for the help!

@skoef skoef closed this as completed May 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants