FreeBSD eats 169.254.x.x addressed packets

Garrett Cooper yanefbsd at gmail.com
Tue Jun 8 18:40:42 UTC 2010


On Tue, Jun 8, 2010 at 11:30 AM, Stephen Clark <sclark46 at earthlink.net> wrote:
> On 06/08/2010 02:21 PM, Guy Helmer wrote:
>>
>> On Jun 8, 2010, at 12:45 PM, Stephen Clark wrote:
>>
>>> Hi,
>>>
>>> Why does FreeBSD 6.3 eat 169.254.x.x addressed packet when
>>> 4.9 didn't?
>>>
>>> ***** 6.3 *****
>>> $ sudo ipfstat -nio
>>> empty list for ipfilter(out)
>>> empty list for ipfilter(in)
>>> Z2984:~
>>> $ ifconfig rl0
>>> rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>  mtu 1500
>>>        options=8<VLAN_MTU>
>>>        inet 192.168.129.1 netmask 0xffffff00 broadcast 192.168.129.255
>>>        inet 169.254.1.1 netmask 0xffff0000 broadcast 169.254.255.255
>>>        ether 00:30:18:ae:7c:77
>>>        media: Ethernet autoselect (100baseTX<full-duplex>)
>>>        status: active
>>> Z2984:~
>>> $ ping 169.254.1.1
>>> PING 169.254.1.1 (169.254.1.1): 56 data bytes
>>> ^C
>>> --- 169.254.1.1 ping statistics ---
>>> 4 packets transmitted, 0 packets received, 100% packet loss
>>> Z2984:~
>>> $ uname -a
>>> FreeBSD Z2984.netwolves.com 6.3-RELEASE-p15 FreeBSD 6.3-RELEASE-p15 #17:
>>> Fri Apr 16 12:51:57 EST 2010
>>>
>>> **** 4.9 *****
>>> FreeBSD H101494.com 4.9-STABLE FreeBSD 4.9-STABLE #59: Thu Mar 30
>>> 13:42:10 EST 2006     root at A1234.com:/mnt2/src/sys/compile/  i386
>>> H101494# ipf -Fa
>>> H101494# ipfstat -nio
>>> empty list for ipfilter(out)
>>> empty list for ipfilter(in)
>>> H101494# ifconfig rl0
>>> rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>  mtu 1500
>>>        inet 10.254.151.1 netmask 0xffffff00 broadcast 10.254.151.255
>>>        inet 10.255.3.30 netmask 0xffffffff broadcast 10.255.3.30
>>>        inet 10.255.4.30 netmask 0xffffffff broadcast 10.255.4.30
>>>        inet 169.254.202.1 netmask 0xffff0000 broadcast 169.254.255.255
>>>        ether 00:30:18:a3:49:b5
>>>        media: Ethernet autoselect (none)
>>>        status: no carrier
>>> H101494# ping 169.254.202.1
>>> PING 169.254.202.1 (169.254.202.1): 56 data bytes
>>> 64 bytes from 169.254.202.1: icmp_seq=0 ttl=64 time=0.052 ms
>>> 64 bytes from 169.254.202.1: icmp_seq=1 ttl=64 time=0.080 ms
>>> 64 bytes from 169.254.202.1: icmp_seq=2 ttl=64 time=0.081 ms
>>> ^C
>>> --- 169.254.202.1 ping statistics ---
>>> 3 packets transmitted, 3 packets received, 0% packet loss
>>> round-trip min/avg/max/stddev = 0.052/0.071/0.081/0.013 ms
>>>
>>>
>>
>>
>> That was a feature added to sys/netinet/in.c and ip_input.c back in 2007
>> to obey RFC 3927 not to output datagrams destined for 169.254.0.0/16.
>>
>> On a system that needed to be able to send datagrams to 169.254.0.0/16
>> addresses, I wrote this patch to add a sysctl knob net.inet.fwd_link_local
>> to dynamically allow a system to send those datagrams:
>>
>>
>> Index: in.c
>> ===================================================================
>> RCS file: /home/ncvs/src/sys/netinet/in.c,v
>> retrieving revision 1.102.2.4.2.1
>> diff -u -r1.102.2.4.2.1 in.c
>> --- in.c        15 Apr 2009 03:14:26 -0000      1.102.2.4.2.1
>> +++ in.c        29 Jul 2009 15:10:42 -0000
>> @@ -67,6 +67,9 @@
>>            struct in_ifaddr *, struct sockaddr_in *, int);
>>  static void   in_purgemaddrs(struct ifnet *);
>>
>> +int ip_fwdlinklocal = 0;
>> +SYSCTL_INT(_net_inet_ip, OID_AUTO, fwd_link_local, CTLFLAG_RW,
>> +       &ip_fwdlinklocal, 0, "Forward link-local addresses");
>>  static int subnetsarelocal = 0;
>>  SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
>>        &subnetsarelocal, 0, "Treat all subnets as directly connected");
>> @@ -129,7 +132,8 @@
>>        register u_long i = ntohl(in.s_addr);
>>        register u_long net;
>>
>> -       if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i) || IN_LINKLOCAL(i))
>> +       if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i) ||
>> +           (!ip_fwdlinklocal&&  IN_LINKLOCAL(i)))
>>                return (0);
>>        if (IN_CLASSA(i)) {
>>                net = i&  IN_CLASSA_NET;
>> Index: ip_input.c
>> ===================================================================
>> RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v
>> retrieving revision 1.332.2.5.2.1
>> diff -u -r1.332.2.5.2.1 ip_input.c
>> --- ip_input.c  15 Apr 2009 03:14:26 -0000      1.332.2.5.2.1
>> +++ ip_input.c  29 Jul 2009 15:10:44 -0000
>> @@ -134,6 +134,7 @@
>>  static struct ifqueue ipintrq;
>>  static int    ipqmaxlen = IFQ_MAXLEN;
>>
>> +extern int ip_fwdlinklocal;
>>  extern        struct domain inetdomain;
>>  extern        struct protosw inetsw[];
>>  u_char        ip_protox[IPPROTO_MAX];
>> @@ -532,7 +533,7 @@
>>                }
>>        }
>>        /* RFC 3927 2.7: Do not forward datagrams for 169.254.0.0/16. */
>> -       if (IN_LINKLOCAL(ntohl(ip->ip_dst.s_addr))) {
>> +       if (!ip_fwdlinklocal&&  IN_LINKLOCAL(ntohl(ip->ip_dst.s_addr))) {
>>                ipstat.ips_cantforward++;
>>                m_freem(m);
>>                return;
>>
>>
>
> Hmmm... how is not responding to pings associated with forwarding?

    Depends on where the box is located that you're pinging from and
to (network topology). It looks like that section of code (and ones
following it in the same function) just drops the packet on the floor
if people attempt to route packets to/from 169.254.x.x.
Thanks,
-Garrett


More information about the freebsd-stable mailing list