Skip to content

the "gateway" primitive correctly implements an incorrect definition #1571

@infrastation

Description

@infrastation

The master branch now has a few "apply" filter tests for gateway, which demonstrate that the current implementation is way less useful than the documentation leads to think. In particular, the man page says:

       gateway host
              True  if the packet used host as a gateway.  I.e., the source or
              the destination Ethernet-like address is host  but  neither  the
              source  nor the destination ARP/IPv4/RARP address is host.  This
              primitive is valid only for the same  link-layer  types  as  the
              ether  host  primitive  above.  May be qualified with a specific
              protocol (arp, ip, rarp).  For example,
                   ip gateway host
              is equivalent to
                   ether host ethernameaddr and not ip host hostnameaddr
              which can be used with either names or numbers for  hostnameaddr
              and ethernameaddr.

In detail:

  • ip gateway HOST means: (the source or the destination MAC address matches) and ((the link-layer protocol is IPv4 and neither the source nor the destination IPv4 address matches) or (the link-layer protocol is not IPv4))
  • arp gateway HOST means: (the source or the destination MAC address matches) and ((the link-layer protocol is ARP and neither the source nor the destination ARP address matches) or (the link-layer protocol is not ARP))
  • rarp gateway HOST means: (the source or the destination MAC address matches) and ((the link-layer protocol is RARP and neither the source nor the destination RARP address matches) or (the link-layer protocol is not RARP))
  • gateway HOST means: (the source or the destination MAC address matches) and ((the link-layer protocol is IPv4 and neither the source nor the destination IPv4 address matches) or (the link-layer protocol is ARP and neither the source nor the destination ARP address matches) or (the link-layer protocol is RARP and neither the source nor the destination RARP address matches) or (the link-layer protocol is neither IPv4 nor ARP nor RARP))

The root cause of this confusion seems to originate in the grammar: for example, not ip src host 1.2.3.4 means exactly the same as ip src host not 1.2.3.4, but a human tends to understand the former as "all packets except those that are IPv4 and have the specified source address" (correct) and the latter as "all IPv4 packets except those that have the specified source address" (incorrect). With this in mind, the informal part of the definition (True if the packet used host as a gateway.) makes perfect sense, but the formal part needs to be different. If the correct solution is to match the protocol separately from the address (not tested!), then:

  • ip gateway HOST would mean: (the source or the destination MAC address matches) and (the link-layer protocol is IPv4) and (neither the source nor the destination IPv4 address matches)
  • arp gateway HOST would mean: (the source or the destination MAC address matches) and (the link-layer protocol is ARP) and (neither the source nor the destination ARP address matches)
  • rarp gateway HOST would mean: (the source or the destination MAC address matches) and (the link-layer protocol is RARP) and (neither the source nor the destination RARP address matches)
  • gateway HOST would mean: (the source or the destination MAC address matches) and (((the link-layer protocol is IPv4) and (neither the source nor the destination IPv4 address matches)) or ((the link-layer protocol is ARP) and (neither the source nor the destination ARP address matches)) or ((the link-layer protocol is RARP) and (neither the source nor the destination RARP address matches)))

One the one hand, the primitive has been defined and implemented this way for a very long time. On the other hand, it has been disabled by default for a very long time too (because until recently it used to be a XOR with IPv6 features, which have been enabled by default). So it seems to me it would make the most sense to fix the definition (with backward compatibility comments) before a future release reintroduces it as an always-on primitive.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions