Bug 242201 - ipfw - option 'ipversion 6' not working
Summary: ipfw - option 'ipversion 6' not working
Status: Closed Works As Intended
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-ipfw mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-11-24 18:46 UTC by Freddy DISSAUX
Modified: 2019-11-27 19:02 UTC (History)
3 users (show)

See Also:


Attachments
Allow using 'ipver 6' as matching rule (359 bytes, patch)
2019-11-26 09:39 UTC, Olivier Cochard
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Freddy DISSAUX 2019-11-24 18:46:39 UTC
From man ipfw:

...
   RULE OPTIONS (MATCH PATTERNS)
...
     ipversion ver
             Matches IP packets whose IP version field is ver.

This option add opcode 'O_IPVER'.

From sys/netpfil/ipfw/ip_fw2.c:

...
    case O_IPVER:
            match = (is_ipv4 && (cmd->arg1 == ip->ip_v));
            break;
...

Flag 'is_ipv4' (may be a copy/paste from another case) must not be used in this case.

Without this flag, i can use the following rule to match ipv6 icmp packet:

/sbin/ipfw add pass log ipversion 6 proto ipv6-icmp


Regards,
Comment 1 Andrey V. Elsukov freebsd_committer 2019-11-26 01:54:03 UTC
I think this opcode was designed to match the ip_v field of IPv4 packets. It was introduced much early than IPv6 support was added.
Comment 2 Freddy DISSAUX 2019-11-26 06:00:04 UTC
The flag is_ipv6 is set by:

...
        /* Identify IP packets and fill up variables. */
        if (pktlen >= sizeof(struct ip6_hdr) &&
            (eh == NULL || eh->ether_type == htons(ETHERTYPE_IPV6)) &&
            ip->ip_v == 6) {
                struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;

                is_ipv6 = 1;
...

Test ip->ip_v seems correct
Comment 3 Olivier Cochard freebsd_committer 2019-11-26 09:39:13 UTC
Created attachment 209447 [details]
Allow using 'ipver 6' as matching rule

Here is a prototype of a patch that fix this problem.
Not sure if I could use is_ipv6() outside an #ifdef INET6.

But with this applied, now using 'ipver 6' as matching rule is fixed:

[root@router]~# ipfw show
00100 4 336 allow ipver 4 proto icmp
00200 8 504 allow ipver 6 proto ipv6-icmp
65535 4 272 deny ip from any to any
Comment 4 Andrey V. Elsukov freebsd_committer 2019-11-26 09:48:29 UTC
As I said before, this opcode is designed to match ip_v field of IPv4 header. It already works as expected.
If you want to match IPv4 or IPv6 packets, you can use corresponding opcodes, they are "ip4" and "ip6".
Comment 5 Freddy DISSAUX 2019-11-27 19:02:10 UTC
Dear Andrey,

You are right. Sorry for the noise,


Regards.