Jira (FACT-1926) ipaddress fact changed behaviour in FreeBSD, returns incorrect result with Puppet 5

43 views
Skip to first unread message

Athanasios Douitsis (JIRA)

unread,
May 22, 2019, 6:11:02 AM5/22/19
to puppe...@googlegroups.com
Athanasios Douitsis created an issue
 
Facter / Bug FACT-1926
ipaddress fact changed behaviour in FreeBSD, returns incorrect result with Puppet 5
Issue Type: Bug Bug
Affects Versions: FACT 3.13.0
Assignee: Unassigned
Created: 2019/05/22 3:10 AM
Priority: Major Major
Reporter: Athanasios Douitsis

The ipaddress fact used to return the main IPv4 address of the system in FreeBSD. Pretty basic I guess, but with Puppet 5, it's broken.

With Puppet5, if there are loopback interfaces (e.g. lo0, lo1) in addition to the usual Ethernet interface (e.g. em0, vmx0, etc), one of the loopback addresses is returned instead. This is obviously wrong and alters an expected behaviour that has been around since Puppet 3 or even before.

Apologies that I cannot really pinpoint or patch the error, but the C++11 code is difficult to grasp. Doing puppet facts --debug yields nothing that could be of any help.

Also, "facterversion": "3.13.2".

Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v7.7.1#77002-sha1:e75ca93)
Atlassian logo

Gheorghe Popescu (JIRA)

unread,
May 28, 2019, 11:05:03 AM5/28/19
to puppe...@googlegroups.com

Gheorghe Popescu (JIRA)

unread,
May 28, 2019, 11:05:03 AM5/28/19
to puppe...@googlegroups.com

Mihai Buzgau (JIRA)

unread,
May 29, 2019, 6:38:04 AM5/29/19
to puppe...@googlegroups.com

Mihai Buzgau (JIRA)

unread,
May 29, 2019, 6:38:04 AM5/29/19
to puppe...@googlegroups.com

Gabriel Nagy (JIRA)

unread,
May 29, 2019, 8:55:04 AM5/29/19
to puppe...@googlegroups.com

Gabriel Nagy (JIRA)

unread,
May 29, 2019, 10:35:03 AM5/29/19
to puppe...@googlegroups.com
Gabriel Nagy commented on Bug FACT-1926
 
Re: ipaddress fact changed behaviour in FreeBSD, returns incorrect result with Puppet 5

Hi,

FreeBSD is community-maintained and as such we do not provide official support for it. However, I tried running this on a FreeBSD machine to reproduce your case.
I added a dummy loopback interface and ran facter:

root@freebsd:~ # ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
 options=81009b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,VLAN_HWFILTER>
 ether 00:0c:29:f1:92:d1
 inet 172.16.230.139 netmask 0xffffff00 broadcast 172.16.230.255 
 media: Ethernet autoselect (1000baseT <full-duplex>)
 status: active
 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
 options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
 inet6 ::1 prefixlen 128 
 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
 inet 127.0.0.1 netmask 0xff000000 
 groups: lo 
 nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
lo1: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
 options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
 inet 5.5.5.5 netmask 0xffff0000 
 groups: lo 
 nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
 
root@freebsd:~ # facter ipaddress
172.16.230.139
 
root@freebsd:~ # uname -a
FreeBSD freebsd 12.0-RELEASE FreeBSD 12.0-RELEASE r341666 GENERIC amd64
root@freebsd:~ # facter facterversion
3.13.0

As shown above, ipaddress points to the em0 IP which is correct.

I also tried to reproduce this on one of our supported OS-es (Ubuntu 18.04) with no avail.

A truss run pointed to /var/db/dhclient.leases.em0 as the file facter parses to show the ipaddress fact.

You can also run facter with the -l debug flag for debug level prints.

Athanasios Douitsis, when you run ifconfig, what is the order of the networks? Does a loopback device come before the ethernet interface? 

Athanasios Douitsis (JIRA)

unread,
May 30, 2019, 6:37:04 PM5/30/19
to puppe...@googlegroups.com

Hello, sorry for the delay,

First of all, you mentioned that the file facter parses /var/db/dhclient.leases.em0. My systems are not using DHCP at all, so I don't think this is related with the bug I'm seeing. I can see that facter tries to run dhcpd -U, search certain dirs under /var, etc, but it isn't there.

When I run

facter -l trace --no-ruby ipaddress

here are the interesting bits:

2019-05-31 00:36:34.328125 DEBUG puppetlabs.facter - no primary interface found: using the first interface with an assigned address as the primary interface.2019-05-31 00:36:34.328197 DEBUG puppetlabs.facter - fact "ipaddress_lo0" has resolved to "127.0.0.1"....2019-05-31 00:36:34.329413 DEBUG puppetlabs.facter - fact "interfaces" has resolved to "lo0,lo1,vmx0".

And then on the final output, I can see that

{{ primary => "lo1"}}

So, it detects the interfaces in an order different than the one that is output from the ifconfig command. The reason is, it never runs the ifconfig command, I checked with dwatch. I'd like to help out, but I cannot yet figure out what exactly it does to get the interfaces. Any help would be appreciated with this (e.g. pointers to code that handles FreeBSD)

 

Gabriel Nagy (JIRA)

unread,
May 31, 2019, 9:52:05 AM5/31/19
to puppe...@googlegroups.com
Gabriel Nagy commented on Bug FACT-1926

Your configuration is somewhat special, as you only have loopback and vmx interfaces.

My run is similar except I have DHCP configured.

What is your output of:

 

$ route -n get default

and

 

$ netstat -rn 

Most of the facter functionality for this resides here: https://github.com/puppetlabs/facter/blob/master/lib/src/facts/bsd/networking_resolver.cc

Athanasios Douitsis (JIRA)

unread,
May 31, 2019, 11:02:06 AM5/31/19
to puppe...@googlegroups.com

I think the culprit may be here: https://github.com/puppetlabs/facter/blob/2aa2d1cd6487f73fb8e311cf027dcf30c2166e28/lib/src/util/bsd/scoped_ifaddrs.cc.

The getifaddrs(3) function is available through <ifaddrs.h> in FreeBSD (and other BSDs I suspect). I'll have to run some checks and see that the getifaddrs function returns.

Athanasios Douitsis (JIRA)

unread,
May 31, 2019, 7:06:03 PM5/31/19
to puppe...@googlegroups.com

Correction, the file I was referring to should have been https://github.com/puppetlabs/facter/blob/master/lib/src/util/bsd/scoped_ifaddrs.cc.

I created this small gist https://gist.github.com/aduitsis/e250baf7bd90d6695eeada20ecd2483f, where I can see that the linked list returned by getifaddrs(3) contains vmx0,lo0,lo1, in that order. That's the same order with the ifconfig output. As we've seen, the lo1 is considered the primary, so I guess it picks the last one. As can be seen in the gist, it is rather easy to discern whether an interface is loopback from its flags. I suspect that the old Ruby code used to do that or it just picked the first interface in the ifconfig output. I also suspect the new C++ code doesn't (yet) have this feature.

Gabriel Nagy (JIRA)

unread,
Jun 7, 2019, 10:06:04 AM6/7/19
to puppe...@googlegroups.com
Gabriel Nagy commented on Bug FACT-1926

Hi,

Are you able to provide the outputs of the commands I mentioned in my previous comment?
If not we'll close this, since we don't support BSDs officially.

Thanks,
Gabriel

Athanasios Douitsis (JIRA)

unread,
Jun 7, 2019, 10:34:02 AM6/7/19
to puppe...@googlegroups.com

Hello,

Did you read the two messages I've sent 6 days ago? The output of those two commands is irrelevant. Facter most probably calls getifaddrs(3) and then messes up the order of the interfaces. Please, read my previous 2 messages.

But let's see the output of the commands too:

5:28pm ~ # route -n get default
{{ route to: 0.0.0.0}}
destination: 0.0.0.0
{{ mask: 0.0.0.0}}
{{ gateway: 147.102.222.200}}
{{ fib: 0}}
{{ interface: vmx0}}
{{ flags: <UP,GATEWAY,DONE,STATIC>}}
{{ recvpipe sendpipe ssthresh rtt,msec mtu weight expire}}
{{ 0 0 0 0 1500 1 0 }}

and

5:28pm ~ # netstat -rn
Routing tables

Internet:
Destination Gateway Flags Netif Expire
default 147.102.222.200 UGS vmx0
127.0.0.1 lo0 UHS lo0
147.102.222.0/24 link#1 U vmx0
147.102.222.96 link#1 UHS lo0
147.102.224.247 link#3 UH lo1

.200 is our gateway, .96 is the system's address. .247 is the loopback address.

Thanks,

Athanasios

Gabriel Nagy (JIRA)

unread,
Jun 7, 2019, 10:48:04 AM6/7/19
to puppe...@googlegroups.com
Gabriel Nagy commented on Bug FACT-1926

Hi,

I did read your messages . Just wanted to confirm my hunch.

Thanks for the output. Assuming your primary interface is vmx0, something similar to the osx implementation needs to be done in bsd/networking_resolver.cc as well: https://github.com/puppetlabs/facter/blob/2aa2d1cd6487f73fb8e311cf027dcf30c2166e28/lib/src/facts/osx/networking_resolver.cc#L52
From what I see, BSD has no specific implementation to figure out the primary interface.

You can tackle it if you are in a rush, I won't be able to get to it until next week.

Cheers

Athanasios Douitsis (JIRA)

unread,
Jun 7, 2019, 10:57:03 AM6/7/19
to puppe...@googlegroups.com

Thanks!

Like I said, FreeBSD does not execute route or any other command so far. I can see that in osx, you're running route with some arguments.

Also, if you take a very quick look at my gist, the getifaddrs returns flags that can yield whether an interface is loopback. So, conceivably, one could use those flags to skip those interfaces like lo0, lo1, etc.

I'm not in a rush at all. I've temporarily overridden the C++11 fact with my own Ruby-based one.

Cheers,

Athanasios

Gabriel Nagy (JIRA)

unread,
Jun 7, 2019, 11:11:02 AM6/7/19
to puppe...@googlegroups.com
Gabriel Nagy commented on Bug FACT-1926

Well we can use the exact same implementation that was done for OS X then (command outputs are very similar if not identical, since OS X also inherits from BSD in a way).

It executes route -n get default, which is the command I requested you to execute, searches the line that begins with "interface: " and gets what's after it, which would be vmx0 in your case.

This sounds like what you want.

Your solution of skipping loopback interfaces sounds good as well, but it doesn't really handle what happens if there are only loopback interfaces present. 

 

Gabriel Nagy (JIRA)

unread,
Jun 10, 2019, 4:02:03 AM6/10/19
to puppe...@googlegroups.com

Gabriel Nagy (JIRA)

unread,
Jun 10, 2019, 4:03:03 AM6/10/19
to puppe...@googlegroups.com
Gabriel Nagy commented on Bug FACT-1926
 
Re: ipaddress fact changed behaviour in FreeBSD, returns incorrect result with Puppet 5

Hi Athanasios Douitsis,

I opened a PR for this: https://github.com/puppetlabs/facter/pull/1788

You can compile facter with the attached patch to confirm it's working: 1788.patch

Cheers

Athanasios Douitsis (JIRA)

unread,
Jun 11, 2019, 9:05:19 AM6/11/19
to puppe...@googlegroups.com

Hello,

I'll have to rebuild the port with the patch applied. Let me get back to you about that within the week.

Athanasios

Athanasios Douitsis (JIRA)

unread,
Jun 11, 2019, 9:40:05 AM6/11/19
to puppe...@googlegroups.com

Okay, I just run a quick test with your patch. With --debug, I get:

 

2019-06-11 16:37:01.358477 DEBUG leatherman.execution:93 - executing command: /sbin/route -n get default
2019-06-11 16:37:01.359456 DEBUG | - route to: 0.0.0.0
2019-06-11 16:37:01.359518 DEBUG | - destination: 0.0.0.0
2019-06-11 16:37:01.359575 DEBUG | - mask: 0.0.0.0
2019-06-11 16:37:01.359624 DEBUG | - gateway: 147.102.222.200
2019-06-11 16:37:01.359678 DEBUG | - fib: 0
2019-06-11 16:37:01.359780 DEBUG | - interface: vmx0
2019-06-11 16:37:01.359872 DEBUG leatherman.execution:469 - completed processing output: closing child pipes.
2019-06-11 16:37:01.359976 DEBUG leatherman.execution:563 - process exited with status code 0.
2019-06-11 16:37:01.360030 DEBUG puppetlabs.facter - got primary interface: "vmx0"

And the final primary interface is changed to vmx0, as it should.

How may I be of further assistance?

Gabriel Nagy (JIRA)

unread,
Jun 11, 2019, 9:44:03 AM6/11/19
to puppe...@googlegroups.com
Gabriel Nagy commented on Bug FACT-1926

Great!

We'll proceed with merging and closing this then.

The fix will get into the next release of facter/puppet-agent.

Athanasios Douitsis (JIRA)

unread,
Jun 11, 2019, 9:52:03 AM6/11/19
to puppe...@googlegroups.com

Many thanks then. I'll let the port maintainer know, in case he wants to include your patch with the present version.

Mihai Buzgau (JIRA)

unread,
Jun 12, 2019, 4:21:10 AM6/12/19
to puppe...@googlegroups.com

Gheorghe Popescu (JIRA)

unread,
Jul 1, 2019, 3:11:02 AM7/1/19
to puppe...@googlegroups.com

Jean Bond (JIRA)

unread,
Jul 1, 2019, 12:18:02 PM7/1/19
to puppe...@googlegroups.com

Gheorghe Popescu (JIRA)

unread,
Jul 3, 2019, 8:09:02 AM7/3/19
to puppe...@googlegroups.com
Gheorghe Popescu updated an issue
Change By: Gheorghe Popescu
Fix Version/s: FACT 3.13.z
Fix Version/s: FACT 3.12.z
Fix Version/s: FACT 3.11.z

Gheorghe Popescu (JIRA)

unread,
Jul 3, 2019, 8:38:03 AM7/3/19
to puppe...@googlegroups.com
Gheorghe Popescu updated an issue
Change By: Gheorghe Popescu
Fix Version/s: FACT 3.13.z
Fix Version/s: FACT 3.12.z
Fix Version/s: FACT 3.11.z
Fix Version/s: FACT 3.13.3
Fix Version/s: FACT 3.12.5
Fix Version/s: FACT 3.11.9
Reply all
Reply to author
Forward
0 new messages