From owner-freebsd-ipfw@FreeBSD.ORG Mon Oct 22 11:07:07 2007 Return-Path: Delivered-To: freebsd-ipfw@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CCA2116A473 for ; Mon, 22 Oct 2007 11:07:07 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id B868C13C4BF for ; Mon, 22 Oct 2007 11:07:07 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.1/8.14.1) with ESMTP id l9MB77p9079975 for ; Mon, 22 Oct 2007 11:07:07 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.1/8.14.1/Submit) id l9MB77xk079971 for freebsd-ipfw@FreeBSD.org; Mon, 22 Oct 2007 11:07:07 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 22 Oct 2007 11:07:07 GMT Message-Id: <200710221107.l9MB77xk079971@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-ipfw@FreeBSD.org Cc: Subject: Current problem reports assigned to freebsd-ipfw@FreeBSD.org X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Oct 2007 11:07:07 -0000 Current FreeBSD problem reports Critical problems Serious problems S Tracker Resp. Description -------------------------------------------------------------------------------- o kern/51274 ipfw [ipfw] [patch] ipfw2 create dynamic rules with parent o kern/73910 ipfw [ipfw] serious bug on forwarding of packets after NAT o kern/74104 ipfw [ipfw] ipfw2/1 conflict not detected or reported, manp o kern/88659 ipfw [modules] ipfw and ip6fw do not work properly as modul o kern/93300 ipfw [ipfw] ipfw pipe lost packets o kern/95084 ipfw [ipfw] [patch] IPFW2 ignores "recv/xmit/via any" (IPFW o kern/97504 ipfw [ipfw] IPFW Rules bug o kern/97951 ipfw [ipfw] [patch] ipfw does not tie interface details to o kern/98831 ipfw [ipfw] ipfw has UDP hickups o kern/102471 ipfw [ipfw] [patch] add tos and dscp support o kern/103454 ipfw [ipfw] [patch] add a facility to modify DF bit of the o kern/106534 ipfw [ipfw] [panic] ipfw + dummynet o kern/112708 ipfw ipfw is seems to be broken to limit number of connecti 13 problems total. Non-critical problems S Tracker Resp. Description -------------------------------------------------------------------------------- a kern/26534 ipfw [ipfw] Add an option to ipfw to log gid/uid of who cau o kern/46159 ipfw [ipfw] [patch] ipfw dynamic rules lifetime feature o kern/48172 ipfw [ipfw] [patch] ipfw does not log size and flags o bin/50749 ipfw [ipfw] [patch] ipfw2 incorrectly parses ports and port o kern/55984 ipfw [ipfw] [patch] time based firewalling support for ipfw o kern/60719 ipfw [ipfw] Headerless fragments generate cryptic error mes o kern/69963 ipfw [ipfw] install_state warning about already existing en o kern/71366 ipfw [ipfw] "ipfw fwd" sometimes rewrites destination mac a o kern/72987 ipfw [ipfw] ipfw/dummynet pipe/queue 'queue [BYTES]KBytes ( o kern/73276 ipfw [ipfw] [patch] ipfw2 vulnerability (parser error) o bin/78785 ipfw [ipfw] [patch] ipfw verbosity locks machine if /etc/rc o kern/80642 ipfw [ipfw] [patch] ipfw small patch - new RULE OPTION o kern/82724 ipfw [ipfw] [patch] Add setnexthop and defaultroute feature o kern/86957 ipfw [ipfw] [patch] ipfw mac logging o kern/87032 ipfw [ipfw] [patch] ipfw ioctl interface implementation o kern/91847 ipfw [ipfw] ipfw with vlanX as the device o kern/103328 ipfw [ipfw] sugestions about ipfw table o kern/104682 ipfw [ipfw] [patch] Some minor language consistency fixes a o bin/104921 ipfw [patch] ipfw(8) sometimes treats ipv6 input as ipv4 (a o kern/105330 ipfw [ipfw] [patch] ipfw (dummynet) does not allow to set q o kern/107305 ipfw [ipfw] ipfw fwd doesn't seem to work o kern/111713 ipfw [dummynet] Too few dummynet queue slots o kern/112561 ipfw [ipfw] ipfw fwd does not work with some TCP packets p kern/113388 ipfw [ipfw][patch] Addition actions with rules within speci o bin/113803 ipfw [patch] bin/ipfw.8 - don't get bitten by the fwd rule o bin/115172 ipfw [patch] ipfw(8) list show some rules with a wrong form p kern/115755 ipfw [ipfw][patch] unify message and add a rule number wher o kern/116009 ipfw [ipfw] [patch] Ignore errors when loading ruleset from 28 problems total. From owner-freebsd-ipfw@FreeBSD.ORG Thu Oct 25 19:16:50 2007 Return-Path: Delivered-To: freebsd-ipfw@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A884B16A41B; Thu, 25 Oct 2007 19:16:50 +0000 (UTC) (envelope-from mlaier@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 6C65813C4BD; Thu, 25 Oct 2007 19:16:50 +0000 (UTC) (envelope-from mlaier@FreeBSD.org) Received: from freefall.freebsd.org (mlaier@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.1/8.14.1) with ESMTP id l9PJGoQY057776; Thu, 25 Oct 2007 19:16:50 GMT (envelope-from mlaier@freefall.freebsd.org) Received: (from mlaier@localhost) by freefall.freebsd.org (8.14.1/8.14.1/Submit) id l9PJGox0057772; Thu, 25 Oct 2007 19:16:50 GMT (envelope-from mlaier) Date: Thu, 25 Oct 2007 19:16:50 GMT Message-Id: <200710251916.l9PJGox0057772@freefall.freebsd.org> To: mlaier@FreeBSD.org, mlaier@FreeBSD.org, freebsd-ipfw@FreeBSD.org From: mlaier@FreeBSD.org Cc: Subject: Re: kern/117234: ipfw send_pkt() and ipfw_tick() don't seem to support IPV6 X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Oct 2007 19:16:50 -0000 Synopsis: ipfw send_pkt() and ipfw_tick() don't seem to support IPV6 Responsible-Changed-From-To: mlaier->freebsd-ipfw Responsible-Changed-By: mlaier Responsible-Changed-When: Thu Oct 25 19:15:51 UTC 2007 Responsible-Changed-Why: Back to the pool, I can't deal with this in a timely manner right now. http://www.freebsd.org/cgi/query-pr.cgi?pr=117234 From owner-freebsd-ipfw@FreeBSD.ORG Thu Oct 25 19:40:03 2007 Return-Path: Delivered-To: freebsd-ipfw@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4130916A418 for ; Thu, 25 Oct 2007 19:40:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 1B3D713C4A8 for ; Thu, 25 Oct 2007 19:40:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.1/8.14.1) with ESMTP id l9PJe2C5059725 for ; Thu, 25 Oct 2007 19:40:02 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.1/8.14.1/Submit) id l9PJe2ne059724; Thu, 25 Oct 2007 19:40:02 GMT (envelope-from gnats) Date: Thu, 25 Oct 2007 19:40:02 GMT Message-Id: <200710251940.l9PJe2ne059724@freefall.freebsd.org> To: freebsd-ipfw@FreeBSD.org From: Max Laier Cc: Subject: Re: kern/117234: ipfw send_pkt() and ipfw_tick() don't seem to support IPV6 X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Max Laier List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Oct 2007 19:40:03 -0000 The following reply was made to PR kern/117234; it has been noted by GNATS. From: Max Laier To: bug-followup@freebsd.org, john.w.court@nokia.com Cc: Subject: Re: kern/117234: ipfw send_pkt() and ipfw_tick() don't seem to support IPV6 Date: Thu, 25 Oct 2007 21:19:01 +0200 --Boundary-00=_owOIHQWJlh8L15h Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline This is an untested patch which could serve as a starting point. -- Max --Boundary-00=_owOIHQWJlh8L15h Content-Type: text/plain; charset="us-ascii"; name="ipfw_v6send.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="ipfw_v6send.diff" Index: ip_fw2.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_fw2.c,v retrieving revision 1.175 diff -u -r1.175 ip_fw2.c --- ip_fw2.c 7 Oct 2007 20:44:23 -0000 1.175 +++ ip_fw2.c 19 Oct 2007 12:38:16 -0000 @@ -98,6 +98,7 @@ #include #include #ifdef INET6 +#include #include #endif @@ -241,6 +242,9 @@ #define IPFW_DYN_UNLOCK() mtx_unlock(&ipfw_dyn_mtx) #define IPFW_DYN_LOCK_ASSERT() mtx_assert(&ipfw_dyn_mtx, MA_OWNED) +static struct mbuf *send_pkt(struct mbuf *, struct ipfw_flow_id *, + u_int32_t, u_int32_t, int); + /* * Timeouts for various events in handing dynamic rules. */ @@ -671,67 +675,25 @@ } static void -send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr *ip6) +send_reject6(struct ip_fw_args *args, int code, u_int hlen, + struct ip6_hdr *ip6) { struct mbuf *m; m = args->m; if (code == ICMP6_UNREACH_RST && args->f_id.proto == IPPROTO_TCP) { struct tcphdr *tcp; - tcp_seq ack, seq; - int flags; - struct { - struct ip6_hdr ip6; - struct tcphdr th; - } ti; tcp = (struct tcphdr *)((char *)ip6 + hlen); - if ((tcp->th_flags & TH_RST) != 0) { - m_freem(m); - args->m = NULL; - return; - } - - ti.ip6 = *ip6; - ti.th = *tcp; - ti.th.th_seq = ntohl(ti.th.th_seq); - ti.th.th_ack = ntohl(ti.th.th_ack); - ti.ip6.ip6_nxt = IPPROTO_TCP; - - if (ti.th.th_flags & TH_ACK) { - ack = 0; - seq = ti.th.th_ack; - flags = TH_RST; - } else { - ack = ti.th.th_seq; - if ((m->m_flags & M_PKTHDR) != 0) { - /* - * total new data to ACK is: - * total packet length, - * minus the header length, - * minus the tcp header length. - */ - ack += m->m_pkthdr.len - hlen - - (ti.th.th_off << 2); - } else if (ip6->ip6_plen) { - ack += ntohs(ip6->ip6_plen) + sizeof(*ip6) - - hlen - (ti.th.th_off << 2); - } else { - m_freem(m); - return; - } - if (tcp->th_flags & TH_SYN) - ack++; - seq = 0; - flags = TH_RST|TH_ACK; + if ((tcp->th_flags & TH_RST) == 0) { + struct mbuf *m0; + m0 = send_pkt(args->m, &(args->f_id), + ntohl(tcp->th_seq), ntohl(tcp->th_ack), + tcp->th_flags | TH_RST); + if (m0 != NULL) + ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); } - bcopy(&ti, ip6, sizeof(ti)); - /* - * m is only used to recycle the mbuf - * The data in it is never read so we don't need - * to correct the offsets or anything - */ - tcp_respond(NULL, ip6, tcp, m, ack, seq, flags); + m_freem(m); } else if (code != ICMP6_UNREACH_RST) { /* Send an ICMPv6 unreach. */ #if 0 /* @@ -1609,13 +1571,16 @@ u_int32_t ack, int flags) { struct mbuf *m; - struct ip *ip; - struct tcphdr *tcp; + int len, dir; + struct ip *h = NULL; /* stupid compiler */ +#ifdef INET6 + struct ip6_hdr *h6 = NULL; +#endif + struct tcphdr *th = NULL; MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == 0) + if (m == NULL) return (NULL); - m->m_pkthdr.rcvif = (struct ifnet *)0; #ifdef MAC if (replyto != NULL) @@ -1626,67 +1591,118 @@ (void)replyto; /* don't warn about unused arg */ #endif - m->m_pkthdr.len = m->m_len = sizeof(struct ip) + sizeof(struct tcphdr); + switch (id->addr_type) { + case 4: + len = sizeof(struct ip) + sizeof(struct tcphdr); + break; +#ifdef INET6 + case 6: + len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr); + break; +#endif + default: + /* XXX: log me?!? */ + m_freem(m); + return (NULL); + } + dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN); + m->m_data += max_linkhdr; + m->m_flags |= M_SKIP_FIREWALL; + m->m_pkthdr.len = m->m_len = len; + m->m_pkthdr.rcvif = NULL; + bzero(m->m_data, len); + + switch (id->addr_type) { + case 4: + h = mtod(m, struct ip *); + + /* prepare for checksum */ + h->ip_p = IPPROTO_TCP; + h->ip_len = htons(sizeof(struct tcphdr)); + if (dir) { + h->ip_src.s_addr = htonl(id->src_ip); + h->ip_dst.s_addr = htonl(id->dst_ip); + } else { + h->ip_src.s_addr = htonl(id->dst_ip); + h->ip_dst.s_addr = htonl(id->src_ip); + } - ip = mtod(m, struct ip *); - bzero(ip, m->m_len); - tcp = (struct tcphdr *)(ip + 1); /* no IP options */ - ip->ip_p = IPPROTO_TCP; - tcp->th_off = 5; - /* - * Assume we are sending a RST (or a keepalive in the reverse - * direction), swap src and destination addresses and ports. - */ - ip->ip_src.s_addr = htonl(id->dst_ip); - ip->ip_dst.s_addr = htonl(id->src_ip); - tcp->th_sport = htons(id->dst_port); - tcp->th_dport = htons(id->src_port); - if (flags & TH_RST) { /* we are sending a RST */ + th = (struct tcphdr *)(h + 1); + break; +#ifdef INET6 + case 6: + h6 = mtod(m, struct ip6_hdr *); + + /* prepare for checksum */ + h6->ip6_nxt = IPPROTO_TCP; + h6->ip6_plen = htons(sizeof(struct tcphdr)); + if (dir) { + h6->ip6_src = id->src_ip6; + h6->ip6_dst = id->dst_ip6; + } else { + h6->ip6_src = id->dst_ip6; + h6->ip6_dst = id->src_ip6; + } + + th = (struct tcphdr *)(h6 + 1); + break; +#endif + } + + if (dir) { + th->th_sport = id->src_port; + th->th_dport = id->dst_port; + } else { + th->th_sport = id->dst_port; + th->th_dport = id->src_port; + } + th->th_off = sizeof(struct tcphdr) >> 2; + + if (flags & TH_RST) { if (flags & TH_ACK) { - tcp->th_seq = htonl(ack); - tcp->th_ack = htonl(0); - tcp->th_flags = TH_RST; + th->th_seq = htonl(ack); + th->th_flags = TH_RST; } else { if (flags & TH_SYN) seq++; - tcp->th_seq = htonl(0); - tcp->th_ack = htonl(seq); - tcp->th_flags = TH_RST | TH_ACK; + th->th_ack = htonl(seq); + th->th_flags = TH_RST | TH_ACK; } } else { /* - * We are sending a keepalive. flags & TH_SYN determines - * the direction, forward if set, reverse if clear. - * NOTE: seq and ack are always assumed to be correct - * as set by the caller. This may be confusing... + * Keepalive - use caller provided sequence numbers */ - if (flags & TH_SYN) { - /* - * we have to rewrite the correct addresses! - */ - ip->ip_dst.s_addr = htonl(id->dst_ip); - ip->ip_src.s_addr = htonl(id->src_ip); - tcp->th_dport = htons(id->dst_port); - tcp->th_sport = htons(id->src_port); - } - tcp->th_seq = htonl(seq); - tcp->th_ack = htonl(ack); - tcp->th_flags = TH_ACK; + th->th_seq = htonl(seq); + th->th_ack = htonl(ack); + th->th_flags = TH_ACK; + } + + switch (id->addr_type) { + case 4: + th->th_sum = in_cksum(m, len); + + /* finish the ip header */ + h->ip_v = 4; + h->ip_hl = sizeof(*h) >> 2; + h->ip_tos = IPTOS_LOWDELAY; + h->ip_off = 0; + h->ip_len = len; + h->ip_ttl = ip_defttl; + h->ip_sum = 0; + break; +#ifdef INET6 + case 6: + th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6), + sizeof(struct tcphdr)); + + /* finish the ip6 header */ + h6->ip6_vfc |= IPV6_VERSION; + h6->ip6_hlim = IPV6_DEFHLIM; + break; +#endif } - /* - * set ip_len to the payload size so we can compute - * the tcp checksum on the pseudoheader - * XXX check this, could save a couple of words ? - */ - ip->ip_len = htons(sizeof(struct tcphdr)); - tcp->th_sum = in_cksum(m, m->m_pkthdr.len); - /* - * now fill fields left out earlier - */ - ip->ip_ttl = ip_defttl; - ip->ip_len = m->m_pkthdr.len; - m->m_flags |= M_SKIP_FIREWALL; + return (m); } @@ -4860,6 +4876,9 @@ ipfw_tick(void * __unused unused) { struct mbuf *m0, *m, *mnext, **mtailp; +#ifdef INET6 + struct mbuf *m6, **m6_tailp; +#endif int i; ipfw_dyn_rule *q; @@ -4874,6 +4893,10 @@ */ m0 = NULL; mtailp = &m0; +#ifdef INET6 + m6 = NULL; + m6_tailp = &m6; +#endif IPFW_DYN_LOCK(); for (i = 0 ; i < curr_dyn_buckets ; i++) { for (q = ipfw_dyn_v[i] ; q ; q = q->next ) { @@ -4889,14 +4912,37 @@ if (TIME_LEQ(q->expire, time_uptime)) continue; /* too late, rule expired */ - *mtailp = send_pkt(NULL, &(q->id), q->ack_rev - 1, + m = send_pkt(NULL, &(q->id), q->ack_rev - 1, q->ack_fwd, TH_SYN); - if (*mtailp != NULL) - mtailp = &(*mtailp)->m_nextpkt; - *mtailp = send_pkt(NULL, &(q->id), q->ack_fwd - 1, + mnext = send_pkt(NULL, &(q->id), q->ack_fwd - 1, q->ack_rev, 0); - if (*mtailp != NULL) - mtailp = &(*mtailp)->m_nextpkt; + + switch (q->id.addr_type) { + case 4: + if (m != NULL) { + *mtailp = m; + mtailp = &(*mtailp)->m_nextpkt; + } + if (mnext != NULL) { + *mtailp = mnext; + mtailp = &(*mtailp)->m_nextpkt; + } + break; +#ifdef INET6 + case 6: + if (m != NULL) { + *m6_tailp = m; + m6_tailp = &(*m6_tailp)->m_nextpkt; + } + if (mnext != NULL) { + *m6_tailp = mnext; + m6_tailp = &(*m6_tailp)->m_nextpkt; + } + break; +#endif + } + + m = mnext = NULL; } } IPFW_DYN_UNLOCK(); @@ -4905,6 +4951,13 @@ m->m_nextpkt = NULL; ip_output(m, NULL, NULL, 0, NULL, NULL); } +#ifdef INET6 + for (m = mnext = m6; m != NULL; m = mnext) { + mnext = m->m_nextpkt; + m->m_nextpkt = NULL; + ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); + } +#endif done: callout_reset(&ipfw_timeout, dyn_keepalive_period*hz, ipfw_tick, NULL); } --Boundary-00=_owOIHQWJlh8L15h--