Index: head/sbin/ipfw/ipfw2.c =================================================================== --- head/sbin/ipfw/ipfw2.c (revision 244438) +++ head/sbin/ipfw/ipfw2.c (working copy) @@ -1159,6 +1159,10 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcw printf("fwd %s", inet_ntop(AF_INET6, &s->sa.sin6_addr, buf, sizeof(buf))); + if (IN6_IS_ADDR_LINKLOCAL(&s->sa.sin6_addr) && + s->sa.sin6_scope_id && + if_indextoname(s->sa.sin6_scope_id, buf)) + printf("%%%s", buf); if (s->sa.sin6_port) printf(",%d", s->sa.sin6_port); } @@ -2888,7 +2892,7 @@ chkarg: struct addrinfo *res; char *s, *end; int family; - u_short port_number; + u_short port_number, scope; NEED1("missing forward address[:port]"); @@ -2919,6 +2923,14 @@ chkarg: ((struct sockaddr_in*)&result)->sin_addr.s_addr = INADDR_ANY; } else { + s = strchr(*av, '%'); + if (s != NULL) { + *(s++) = '\0'; + scope = if_nametoindex(s); + if (scope == 0) + err(EX_DATAERR, "ifname %s", s); + } else + scope = 0; /* * Resolve the host name or address to a family and a * network representation of the address. @@ -2957,10 +2969,13 @@ chkarg: p->sa.sin6_family = AF_INET6; p->sa.sin6_port = port_number; p->sa.sin6_flowinfo = 0; - p->sa.sin6_scope_id = 0; /* No table support for v6 yet. */ bcopy(&((struct sockaddr_in6*)&result)->sin6_addr, &p->sa.sin6_addr, sizeof(p->sa.sin6_addr)); + if (IN6_IS_ADDR_LINKLOCAL(&p->sa.sin6_addr) && scope) + p->sa.sin6_scope_id = scope; + else + p->sa.sin6_scope_id = 0; } else { errx(EX_DATAERR, "Invalid address family in forward action"); } Index: head/sys/netpfil/ipfw/ip_fw_sockopt.c =================================================================== --- head/sys/netpfil/ipfw/ip_fw_sockopt.c (revision 244438) +++ head/sys/netpfil/ipfw/ip_fw_sockopt.c (working copy) @@ -60,6 +60,9 @@ __FBSDID("$FreeBSD$"); #include #include /* hooks */ #include +#ifdef INET6 +#include +#endif #include @@ -711,6 +714,7 @@ check_ipfw_struct(struct ip_fw *rule, int size) case O_FORWARD_IP6: if (cmdlen != F_INSN_SIZE(ipfw_insn_sa6)) goto bad_size; + sa6_embedscope(&((ipfw_insn_sa6 *)cmd)->sa, 0); goto check_action; #endif /* INET6 */