We couldn't specify the rule for filtering tunnel traffic since an

IPv6 support was committed:

- Stop treating `ip' and `ipv6' as special in `proto' option as they
  conflict with /etc/protocols.

- Disuse `ipv4' in `proto' option as it is corresponding to `ipv6'.

- When protocol is specified as numeric, treat it as it is even it is
  41 (ipv6).

- Allow zero for protocol as it is valid number of `ip'.

Still, we cannot specify an IPv6 over an IPv4 tunnel like before such
as:

	pass ipv6 from any to any

But, now, you can specify it like:

	pass ip4 from any to any proto ipv6

PR:		kern/89472
Reported by:	Ga l Roualland <gael.roualland__at__dial.oleane.com>
MFC after:	1 week
This commit is contained in:
ume 2005-11-29 15:25:09 +00:00
parent fd9fb6b272
commit b9221a7b29
2 changed files with 62 additions and 16 deletions

View File

@ -844,6 +844,19 @@ Matches any packet.
.El
.Pp
The
.Cm ip
and
.Cm ipv6
in
.Cm proto
option will be treated as inner protocol.
And, the
.Cm ipv4
is not available in
.Cm proto
option.
.Pp
The
.Cm { Ar protocol Cm or ... }
format (an
.Em or-block )

View File

@ -1109,7 +1109,7 @@ print_ip6(ipfw_insn_ip6 *cmd, char const *s)
return;
}
if (cmd->o.opcode == O_IP6) {
printf(" ipv6");
printf(" ip6");
return;
}
@ -1178,7 +1178,7 @@ print_icmp6types(ipfw_insn_u32 *cmd)
int i, j;
char sep= ' ';
printf(" ipv6 icmp6types");
printf(" ip6 icmp6types");
for (i = 0; i < 7; i++)
for (j=0; j < 32; ++j) {
if ( (cmd->d[i] & (1 << (j))) == 0)
@ -1897,11 +1897,11 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth)
break;
case O_IP6:
printf(" ipv6");
printf(" ip6");
break;
case O_IP4:
printf(" ipv4");
printf(" ip4");
break;
case O_ICMP6TYPE:
@ -3590,30 +3590,63 @@ add_mactype(ipfw_insn *cmd, int ac, char *av)
}
static ipfw_insn *
add_proto(ipfw_insn *cmd, char *av, u_char *proto)
add_proto0(ipfw_insn *cmd, char *av, u_char *protop)
{
struct protoent *pe;
char *ep;
int proto;
*proto = IPPROTO_IP;
proto = strtol(av, &ep, 0);
if (*ep != '\0' || proto < 0) {
if ((pe = getprotobyname(av)) == NULL)
return NULL;
proto = pe->p_proto;
}
fill_cmd(cmd, O_PROTO, 0, proto);
*protop = proto;
return cmd;
}
static ipfw_insn *
add_proto(ipfw_insn *cmd, char *av, u_char *protop)
{
u_char proto = IPPROTO_IP;
if (_substrcmp(av, "all") == 0)
; /* do not set O_IP4 nor O_IP6 */
else if (strcmp(av, "ip4") == 0)
/* explicit "just IPv4" rule */
fill_cmd(cmd, O_IP4, 0, 0);
else if (strcmp(av, "ip6") == 0) {
/* explicit "just IPv6" rule */
proto = IPPROTO_IPV6;
fill_cmd(cmd, O_IP6, 0, 0);
} else
return add_proto0(cmd, av, protop);
*protop = proto;
return cmd;
}
static ipfw_insn *
add_proto_compat(ipfw_insn *cmd, char *av, u_char *protop)
{
u_char proto = IPPROTO_IP;
if (_substrcmp(av, "all") == 0 || strcmp(av, "ip") == 0)
; /* do not set O_IP4 nor O_IP6 */
else if (strcmp(av, "ipv4") == 0 || strcmp(av, "ip4") == 0)
/* explicit "just IPv4" rule */
fill_cmd(cmd, O_IP4, 0, 0);
else if (strcmp(av, "ipv6") == 0 || strcmp(av, "ip6") == 0) {
/* explicit "just IPv6" rule */
*proto = IPPROTO_IPV6;
proto = IPPROTO_IPV6;
fill_cmd(cmd, O_IP6, 0, 0);
} else if ((*proto = atoi(av)) > 0)
; /* all done! */
else if ((pe = getprotobyname(av)) != NULL)
*proto = pe->p_proto;
else
return NULL;
if (*proto != IPPROTO_IP && *proto != IPPROTO_IPV6)
fill_cmd(cmd, O_PROTO, 0, *proto);
} else
return add_proto0(cmd, av, protop);
*protop = proto;
return cmd;
}
@ -4056,7 +4089,7 @@ add(int ac, char *av[])
OR_START(get_proto);
NOT_BLOCK;
NEED1("missing protocol");
if (add_proto(cmd, *av, &proto)) {
if (add_proto_compat(cmd, *av, &proto)) {
av++; ac--;
if (F_LEN(cmd) != 0) {
prev = cmd;