netfilter: IPv6 NAT
Subsystems (5)
cover netfilter: IPv6 NAT
The following patches contain an updated version of IPv6 NAT against Linus' current tree.
The series is organized as follows:
- Patches 01-03 contain bugfixes for SIP helper bugs/regressions present in the current kernel
- Patches 04-06 improve conntrack fragmentation handling, the IPv6 parts are also a precondition for IPv6 NAT
- Patches 07 and 08 prepare the current NAT code for conversion to an address family independant core, but contain no functional changes
- Patch 09 adds the address family independant NAT core and converts the existing IPv4-only NAT code to an AF-specific module
- Patches 10 and 11 add some infrastructure for IPv6 NAT
- Patch 12 adds IPv6 NAT support
- Patches 13-15 add IPv6 specific NAT targets
- Patches 16-19 add some IPv6-capable ports of existing NAT helpers
- Patch 19 is independant of the IPv6 NAT code and adds support for stateless IPv6 prefix translation, just to relieve my conscience ;)
Since the last posting numerous bugs have been fixed, I don't remember all of them, the more important ones include:
- automatic NAT module loading in ctnetlink
- address selection when mapping to IPv6 ranges
- handling of IPv6 fragments
- NAT handling of ICMPv6 error messages
Besides implementing IPv6 NAT, there are no known bugs left. Userspace patches will follow shortly.
The entire patchset is also available at
git://github.com/kaber/nf-nat-ipv6.git master
Comments, questions and test results welcome.
PATCH 1/19 netfilter: nf_ct_sip: fix helper name
From: Patrick McHardy <[email protected]>
Commit 3a8fc53a (netfilter: nf_ct_helper: allocate 16 bytes for the helper and policy names) introduced a bug in the SIP helper, the helper name is sprinted to the sip_names array instead of instead of into the helper structure. This breaks the helper match and the /proc/net/nf_conntrack_expect output.
--- net/netfilter/nf_conntrack_sip.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)
net/netfilter/nf_conntrack_sip.c +2 -3
@@ -1515,7 +1515,6 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff, }static struct nf_conntrack_helper sip[MAX_PORTS ][4 ]__read_mostly ; -static char sip_names[MAX_PORTS ][4 ][sizeof ("sip-65535" )]__read_mostly ;static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX +1 ] = { [SIP_EXPECT_SIGNALLING ] = {
@@ -1585,9 +1584,9 @@ static int __init nf_conntrack_sip_init(void) sip[i][j].me =THIS_MODULE ;if (ports[i] ==SIP_PORT ) -sprintf (sip_names[i][j],"sip" ); +sprintf (sip[i][j].name,"sip" );else -sprintf (sip_names[i][j],"sip-%u" , i); +sprintf (sip[i][j].name,"sip-%u" , i);pr_debug ("port #%u: %u\n" , i, ports[i]);
Signature · 1 line
1.7.1
Re: [PATCH 01/19] netfilter: nf_ct_sip: fix helper name
Quoted 7 lines · On Thu, Aug 09, 2012 at 10:08:45PM +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
Commit
3a8fc53a(netfilter:nf_ct_helper: allocate 16 bytes for the helper and policy names) introduced a bug in the SIP helper, the helper name is sprinted to thesip_namesarray instead of instead of into the helper structure. This breaks the helper match and the/proc/net/nf_conntrack_expectoutput.
Applied, thanks Patrick.
PATCH 2/19 netfilter: nf_ct_sip: fix IPv6 address parsing
In reply to [email protected]From: Patrick McHardy <[email protected]>
Within SIP messages IPv6 addresses are enclosed in square brackets in most cases, with the exception of the "received=" header parameter. Currently the helper fails to parse enclosed addresses.
This patch:
- changes the SIP address parsing function to enforce square brackets when required, and accept them when not required but present, as recommended by RFC 5118.
- adds a new SDP address parsing function that never accepts square brackets since SDP doesn't use them.
With these changes, the SIP helper correctly parses all test messages from RFC 5118 (Session Initiation Protocol (SIP) Torture Test Messages for Internet Protocol Version 6 (IPv6)).
--- include/linux/netfilter/nf_conntrack_sip.h | 2 +- net/ipv4/netfilter/nf_nat_sip.c | 4 +- net/netfilter/nf_conntrack_sip.c | 87 ++++++++++++++++++++++------ 3 files changed, 73 insertions(+), 20 deletions(-)
include/linux/netfilter/nf_conntrack_sip.h +1 -1
@@ -164,7 +164,7 @@ extern int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr unsigned int dataoff, unsigned int datalen, const char *name, unsigned int *matchoff, unsigned int *matchlen, - union nf_inet_addr *addr); + union nf_inet_addr *addr, bool delim); extern int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr, unsigned int off, unsigned int datalen, const char *name,
net/ipv4/netfilter/nf_nat_sip.c +2 -2
@@ -173,7 +173,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,* the reply. */ if (ct_sip_parse_address_param (ct, *dptr, matchend, *datalen,"maddr=" , &poff, &plen, - &addr) >0 && + &addr, true) >0 && addr.ip == ct->tuplehash[dir].tuple.src.u3.ip && addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) { buflen = sprintf(buffer, "%pI4",
@@ -187,7 +187,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,* from which the server received the request. */ if (ct_sip_parse_address_param (ct, *dptr, matchend, *datalen,"received=" , &poff, &plen, - &addr) >0 && + &addr, false) >0 && addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip && addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) { buflen = sprintf(buffer, "%pI4",
net/netfilter/nf_conntrack_sip.c +70 -17
157 lines not on this page · raw message
Signature · 1 line
1.7.1
Re: [PATCH 02/19] netfilter: nf_ct_sip: fix IPv6 address parsing
Quoted 12 lines · On Thu, Aug 09, 2012 at 10:08:46PM +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
Within SIP messages IPv6 addresses are enclosed in square brackets in most cases, with the exception of the "received=" header parameter. Currently the helper fails to parse enclosed addresses.
This patch:
- changes the SIP address parsing function to enforce square brackets when required, and accept them when not required but present, as recommended by RFC 5118.
Quoted 6 lines
- adds a new SDP address parsing function that never accepts square brackets since SDP doesn't use them.
With these changes, the SIP helper correctly parses all test messages from RFC 5118 (Session Initiation Protocol (SIP) Torture Test Messages for Internet Protocol Version 6 (IPv6)).
Applied, thanks Patrick.
PATCH 3/19 netfilter: nf_nat_sip: fix via header translation with multiple parameters
In reply to [email protected]From: Patrick McHardy <[email protected]>
Via-headers are parsed beginning at the first character after the Via-address. When the address is translated first and its length decreases, the offset to start parsing at is incorrect and header parameters might be missed.
Update the offset after translating the Via-address to fix this.
--- net/ipv4/netfilter/nf_nat_sip.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
net/ipv4/netfilter/nf_nat_sip.c +3 -2
@@ -148,7 +148,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff,if (ct_sip_parse_header_uri (ct, *dptr,NULL , *datalen, hdr,NULL , &matchoff, &matchlen, &addr, &port) >0 ) { -unsigned int matchend, poff, plen, buflen, n; +unsigned int olen, matchend, poff, plen, buflen, n;char buffer[sizeof ("nnn.nnn.nnn.nnn:nnnnn" )];/* We're only interested in headers related to this
@@ -163,11 +163,12 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff, goto next; } + olen = *datalen;if (!map_addr (skb, dataoff, dptr, datalen, matchoff, matchlen, &addr, port))return NF_DROP ; - matchend = matchoff + matchlen; + matchend = matchoff + matchlen + *datalen - olen;/* The maddr= parameter (RFC 2361) specifies where to send * the reply. */
Signature · 1 line
1.7.1
Re: [PATCH 03/19] netfilter: nf_nat_sip: fix via header translation with multiple parameters
Quoted 7 lines · On Thu, Aug 09, 2012 at 10:08:47PM +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
Via-headers are parsed beginning at the first character after the Via-address. When the address is translated first and its length decreases, the offset to start parsing at is incorrect and header parameters might be missed.
Update the offset after translating the Via-address to fix this.
Applied, thanks Patrick.
Re: [PATCH 03/19] netfilter: nf_nat_sip: fix via header translation with multiple parameters
Quoted 10 lines · Pablo Neira Ayuso
Quoted 7 lines · On Thu, Aug 09, 2012 at 10:08:47PM +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
Via-headers are parsed beginning at the first character after the Via-address. When the address is translated first and its length decreases, the offset to start parsing at is incorrect and header parameters might be missed.
Update the offset after translating the Via-address to fix this.
Applied, thanks Patrick.
Thanks Pablo. I'll submit the final IPv6-NAT patches once these three patches have made it into net-next/nf-next.
PATCH 4/19 ipv4: fix path MTU discovery with connection tracking
In reply to [email protected]From: Patrick McHardy <[email protected]>
IPv4 conntrack defragments incoming packet at the PRE_ROUTING hook and (in case of forwarded packets) refragments them at POST_ROUTING independant of the IP_DF flag. Refragmentation uses the dst_mtu() of the local route without caring about the original fragment sizes, thereby breaking PMTUD.
This patch fixes this by keeping track of the largest received fragment with IP_DF set and generates an ICMP fragmentation required error during refragmentation if that size exceeds the MTU.
--- include/net/inet_frag.h | 2 ++ include/net/ip.h | 2 ++ net/ipv4/ip_fragment.c | 8 +++++++- net/ipv4/ip_output.c | 4 +++- 4 files changed, 14 insertions(+), 2 deletions(-)
include/net/inet_frag.h +2 -0
@@ -29,6 +29,8 @@ struct inet_frag_queue {#define INET_FRAG_COMPLETE 4#define INET_FRAG_FIRST_IN 2#define INET_FRAG_LAST_IN 1 + +u16 max_size; };#define INETFRAGS_HASHSZ 64
include/net/ip.h +2 -0
@@ -42,6 +42,8 @@ struct inet_skb_parm {#define IPSKB_XFRM_TRANSFORMED 4#define IPSKB_FRAG_COMPLETE 8#define IPSKB_REROUTED 16 + +u16 frag_max_size; };static inline unsigned int ip_hdrlen (const struct sk_buff *skb)
net/ipv4/ip_fragment.c +7 -1
@@ -523,6 +523,10 @@ found:if (offset ==0 ) qp->q.last_in |=INET_FRAG_FIRST_IN ; +if (ip_hdr (skb)->frag_off &htons (IP_DF ) && + skb->len + ihl > qp->q.max_size) + qp->q.max_size = skb->len + ihl; +if (qp->q.last_in == (INET_FRAG_FIRST_IN |INET_FRAG_LAST_IN ) && qp->q.meat == qp->q.len)return ip_frag_reasm (qp, prev, dev);
@@ -646,9 +650,11 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, head->next =NULL ; head->dev = dev; head->tstamp = qp->q.stamp; +IPCB (head)->frag_max_size = qp->q.max_size; iph =ip_hdr (head); - iph->frag_off =0 ; +/* max_size != 0 implies at least one fragment had IP_DF set */ + iph->frag_off = qp->q.max_size ?htons (IP_DF ) :0 ; iph->tot_len =htons (len); iph->tos |= ecn;IP_INC_STATS_BH (net,IPSTATS_MIB_REASMOKS );
net/ipv4/ip_output.c +3 -1
@@ -467,7 +467,9 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) iph =ip_hdr (skb); -if (unlikely ((iph->frag_off &htons (IP_DF )) && !skb->local_df)) { +if (unlikely (((iph->frag_off &htons (IP_DF )) && !skb->local_df) || + (IPCB (skb)->frag_max_size && +IPCB (skb)->frag_max_size >dst_mtu (&rt->dst)))) {IP_INC_STATS (dev_net (dev),IPSTATS_MIB_FRAGFAILS );icmp_send (skb,ICMP_DEST_UNREACH ,ICMP_FRAG_NEEDED ,htonl (ip_skb_dst_mtu (skb)));
Signature · 1 line
1.7.1
PATCH 5/19 netfilter: nf_conntrack_ipv6: improve fragmentation handling
In reply to [email protected]From: Patrick McHardy <[email protected]>
The IPv6 conntrack fragmentation currently has a couple of shortcomings. Fragmentes are collected in PREROUTING/OUTPUT, are defragmented, the defragmented packet is then passed to conntrack, the resulting conntrack information is attached to each original fragment and the fragments then continue their way through the stack.
Helper invocation occurs in the POSTROUTING hook, at which point only the original fragments are available. The result of this is that fragmented packets are never passed to helpers.
This patch improves the situation in the following way:
- If a reassembled packet belongs to a connection that has a helper assigned, the reassembled packet is passed through the stack instead of the original fragments.
- During defragmentation, the largest received fragment size is stored. On output, the packet is refragmented if required. If the largest received fragment size exceeds the outgoing MTU, a "packet too big" message is generated, thus behaving as if the original fragments were passed through the stack from an outside point of view.
- The ipv6_helper() hook function can't receive fragments anymore for connections using a helper, so it is switched to use ipv6_skip_exthdr() instead of the netfilter specific nf_ct_ipv6_skip_exthdr() and the reassembled packets are passed to connection tracking helpers.
The result of this is that we can properly track fragmented packets, but still generate ICMPv6 Packet too big messages if we would have before.
This patch is also required as a precondition for IPv6 NAT, where NAT helpers might enlarge packets up to a point that they require fragmentation. In that case we can't generate Packet too big messages since the proper MTU can't be calculated in all cases (f.i. when changing textual representation of a variable amount of addresses), so the packet is transparently fragmented iff the original packet or fragments would have fit the outgoing MTU.
--- include/linux/ipv6.h | 1 + net/ipv6/ip6_output.c | 7 +++- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 37 ++++++++++++++++++------ net/ipv6/netfilter/nf_conntrack_reasm.c | 19 ++++++++++-- 4 files changed, 50 insertions(+), 14 deletions(-)
include/linux/ipv6.h +1 -0
@@ -256,6 +256,7 @@ struct inet6_skb_parm {#if defined(CONFIG_IPV6_MIP6 ) || defined(CONFIG_IPV6_MIP6_MODULE )__u16 dsthao;#endif +__u16 frag_max_size;#define IP6SKB_XFRM_TRANSFORMED 1#define IP6SKB_FORWARDED 2
net/ipv6/ip6_output.c +5 -2
@@ -493,7 +493,8 @@ int ip6_forward(struct sk_buff *skb)if (mtu <IPV6_MIN_MTU ) mtu =IPV6_MIN_MTU ; -if (skb->len > mtu && !skb_is_gso (skb)) { +if ((!skb->local_df && skb->len > mtu && !skb_is_gso (skb)) || + (IP6CB (skb)->frag_max_size &&IP6CB (skb)->frag_max_size > mtu)) {/* Again, force OUTPUT device used as source address */ skb->dev = dst->dev;icmpv6_send (skb,ICMPV6_PKT_TOOBIG ,0 , mtu);
@@ -636,7 +637,9 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))/* We must not fragment if the socket is set to force MTU discovery * or if the skb it not generated by a local socket. */ -if (unlikely (!skb->local_df && skb->len > mtu)) { +if (unlikely (!skb->local_df && skb->len > mtu) || + (IP6CB (skb)->frag_max_size && +IP6CB (skb)->frag_max_size > mtu)) {if (skb->sk &&dst_allfrag (skb_dst (skb)))sk_nocaps_add (skb->sk,NETIF_F_GSO_MASK );
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +28 -9
@@ -153,10 +153,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,const struct nf_conn_help *help;const struct nf_conntrack_helper *helper;enum ip_conntrack_info ctinfo; -unsigned int ret, protoff; -unsigned int extoff = (u8 *)(ipv6_hdr (skb) +1 ) - skb->data; -unsigned char pnum =ipv6_hdr (skb)->nexthdr; - +unsigned int ret; +__be16 frag_off; +int protoff; +u8 nexthdr;/* This is where we call the helper: as the packet goes out. */ ct =nf_ct_get (skb, &ctinfo);
@@ -171,9 +171,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,if (!helper)return NF_ACCEPT ; - protoff =nf_ct_ipv6_skip_exthdr (skb, extoff, &pnum, - skb->len - extoff); -if (protoff > skb->len || pnum ==NEXTHDR_FRAGMENT ) { + nexthdr =ipv6_hdr (skb)->nexthdr; + protoff =ipv6_skip_exthdr (skb,sizeof (struct ipv6hdr ), &nexthdr, + &frag_off); +if (protoff <0 || (frag_off &ntohs (~0x7 )) !=0 ) {pr_debug ("proto header not found\n" );return NF_ACCEPT ; }
@@ -199,9 +200,13 @@ static unsigned int ipv6_confirm(unsigned int hooknum,static unsigned int __ipv6_conntrack_in (struct net *net,unsigned int hooknum,struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out,int (*okfn)(struct sk_buff *)) {struct sk_buff *reasm = skb->nfct_reasm; +struct nf_conn *ct; +enum ip_conntrack_info ctinfo;/* This packet is fragmented and has reassembled packet. */ if (reasm) {
@@ -213,6 +218,20 @@ static unsigned int __ipv6_conntrack_in(struct net *net,if (ret !=NF_ACCEPT )return ret; } + +/* Conntrack helpers need the entire reassembled packet in the +* POST_ROUTING hook. +*/ + ct =nf_ct_get (reasm, &ctinfo); +if (ct !=NULL &&test_bit (IPS_HELPER_BIT , &ct->status)) { +nf_conntrack_get_reasm (skb); +NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, reasm, + (struct net_device *)in, + (struct net_device *)out, + okfn,NF_IP6_PRI_CONNTRACK +1 ); +return NF_DROP_ERR (-ECANCELED ); + } +nf_conntrack_get (reasm->nfct); skb->nfct = reasm->nfct; skb->nfctinfo = reasm->nfctinfo;
@@ -228,7 +247,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum, const struct net_device *out, int (*okfn)(struct sk_buff *)) { - return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn); + return __ipv6_conntrack_in(dev_net(in), hooknum, skb, in, out, okfn); } static unsigned int ipv6_conntrack_local(unsigned int hooknum,
@@ -242,7 +261,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,net_notice_ratelimited ("ipv6_conntrack_local: packet too short\n" );return NF_ACCEPT ; } -return __ipv6_conntrack_in (dev_net (out), hooknum, skb, okfn); +return __ipv6_conntrack_in (dev_net (out), hooknum, skb, in, out, okfn); }static struct nf_hook_ops ipv6_conntrack_ops[]__read_mostly = {
net/ipv6/netfilter/nf_conntrack_reasm.c +16 -3
@@ -190,6 +190,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, const struct frag_hdr *fhdr, int nhoff) {struct sk_buff *prev, *next; +unsigned int payload_len;int offset, end;if (fq->q.last_in &INET_FRAG_COMPLETE ) {
@@ -197,8 +198,10 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, goto err; } + payload_len =ntohs (ipv6_hdr (skb)->payload_len); + offset =ntohs (fhdr->frag_off) & ~0x7 ; - end = offset + (ntohs (ipv6_hdr (skb)->payload_len) - + end = offset + (payload_len - ((u8 *)(fhdr +1 ) - (u8 *)(ipv6_hdr (skb) +1 )));if ((unsigned int )end >IPV6_MAXPLEN ) {
@@ -307,6 +310,8 @@ found: skb->dev =NULL ; fq->q.stamp = skb->tstamp; fq->q.meat += skb->len; +if (payload_len > fq->q.max_size) + fq->q.max_size = payload_len;atomic_add (skb->truesize, &nf_init_frags.mem);/* The first fragment.
@@ -412,10 +417,12 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) }atomic_sub (head->truesize, &nf_init_frags.mem); + head->local_df =1 ; head->next =NULL ; head->dev = dev; head->tstamp = fq->q.stamp;ipv6_hdr (head)->payload_len =htons (payload_len); +IP6CB (head)->frag_max_size =sizeof (struct ipv6hdr ) + fq->q.max_size;/* Yes, and fold redundant checksum back. 8) */ if (head->ip_summed ==CHECKSUM_COMPLETE )
@@ -592,6 +599,7 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, int (*okfn)(struct sk_buff *)) {struct sk_buff *s, *s2; +unsigned int ret =0 ;for (s =NFCT_FRAG6_CB (skb)->orig; s;) {nf_conntrack_put_reasm (s->nfct_reasm);
@@ -601,8 +609,13 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, s2 = s->next; s->next =NULL ; -NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, s, in, out, okfn, -NF_IP6_PRI_CONNTRACK_DEFRAG +1 ); +if (ret != -ECANCELED ) + ret =NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, s, + in, out, okfn, +NF_IP6_PRI_CONNTRACK_DEFRAG +1 ); +else +kfree_skb (s); + s = s2; }nf_conntrack_put_reasm (skb);
Signature · 1 line
1.7.1
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 12 lines · On Thu, 2012-08-09 at 22:08 +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
The IPv6 conntrack fragmentation currently has a couple of shortcomings. Fragmentes are collected in PREROUTING/OUTPUT, are defragmented, the defragmented packet is then passed to conntrack, the resulting conntrack information is attached to each original fragment and the fragments then continue their way through the stack.
Helper invocation occurs in the POSTROUTING hook, at which point only the original fragments are available. The result of this is that fragmented packets are never passed to helpers.
Quoted 5 lines
This patch improves the situation in the following way:
- If a reassembled packet belongs to a connection that has a helper assigned, the reassembled packet is passed through the stack instead of the original fragments.
I'm working on IPv6 fragment handling for IPVS, and are taking advantage of the "replay" by nf_ct_frag6_output() at hook prio -399 (NF_IP6_PRI_CONNTRACK_DEFRAG + 1).
By making a hook at NF_INET_PRE_ROUTING at prio -99 (NF_IP6_PRI_NAT_DST
+ 1).
I can see that the code path can be changed (with this patch), if a helper is assigned. Then the "replay" starts at prio -199 (NF_IP6_PRI_CONNTRACK + 1), I guess I'm safe as I run at -99.
I have tested that your patchset works, with my ipvs patches, but would like the trigger the changed code path, to make sure.
Could you provide an iptables command/rule, that trigger this code path?
[cut]
Quoted 19 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +5
-0@@ -199,9 +200,13 @@ static unsigned int ipv6_confirm(unsigned int hooknum,static unsigned int __ipv6_conntrack_in (struct net *net,unsigned int hooknum,struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out,int (*okfn)(struct sk_buff *)) {struct sk_buff *reasm = skb->nfct_reasm; +struct nf_conn *ct; +enum ip_conntrack_info ctinfo;/* This packet is fragmented and has reassembled packet. */ if (reasm) {@@ -213,6 +218,20 @@ static unsigned int __ipv6_conntrack_in(struct net *net,if (ret !=NF_ACCEPT )return ret; } +
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c static unsigned int __ipv6_conntrack_in(struct net *net, · line 231
Quoted 10 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +10
-0+/* Conntrack helpers need the entire reassembled packet in the +* POST_ROUTING hook. +*/ + ct =nf_ct_get (reasm, &ctinfo); +if (ct !=NULL &&test_bit (IPS_HELPER_BIT , &ct->status)) { +nf_conntrack_get_reasm (skb); +NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, reasm, + (struct net_device *)in, + (struct net_device *)out, + okfn,NF_IP6_PRI_CONNTRACK +1 );
Hook prio change to NF_IP6_PRI_CONNTRACK + 1
Quoted 2 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +2
-0+return NF_DROP_ERR (-ECANCELED ); + }
[cut]
Quoted 9 lines
net/ipv6/netfilter/nf_conntrack_reasm.c +1
-0@@ -592,6 +599,7 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, int (*okfn)(struct sk_buff *)) {struct sk_buff *s, *s2; +unsigned int ret =0 ;for (s =NFCT_FRAG6_CB (skb)->orig; s;) {nf_conntrack_put_reasm (s->nfct_reasm);
net/ipv6/netfilter/nf_conntrack_reasm.c void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, · line 615
Quoted 9 lines
net/ipv6/netfilter/nf_conntrack_reasm.c +4
-2@@ -601,8 +609,13 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, s2 = s->next; s->next =NULL ; -NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, s, in, out, okfn, -NF_IP6_PRI_CONNTRACK_DEFRAG +1 ); +if (ret != -ECANCELED ) + ret =NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, s, + in, out, okfn, +NF_IP6_PRI_CONNTRACK_DEFRAG +1 );
Old hook prio
Quoted 6 lines
net/ipv6/netfilter/nf_conntrack_reasm.c +3
-0+else +kfree_skb (s); + s = s2; }nf_conntrack_put_reasm (skb);
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 25 lines · Jesper Dangaard Brouer
Quoted 12 lines · On Thu, 2012-08-09 at 22:08 +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
The IPv6 conntrack fragmentation currently has a couple of shortcomings. Fragmentes are collected in PREROUTING/OUTPUT, are defragmented, the defragmented packet is then passed to conntrack, the resulting conntrack information is attached to each original fragment and the fragments then continue their way through the stack.
Helper invocation occurs in the POSTROUTING hook, at which point only the original fragments are available. The result of this is that fragmented packets are never passed to helpers.
Quoted 5 lines
This patch improves the situation in the following way:
- If a reassembled packet belongs to a connection that has a helper assigned, the reassembled packet is passed through the stack instead of the original fragments.
I'm working on IPv6 fragment handling for IPVS, and are taking advantage of the "replay" by
nf_ct_frag6_output()at hook prio -399 (NF_IP6_PRI_CONNTRACK_DEFRAG+ 1).
By making a hook atNF_INET_PRE_ROUTINGat prio -99 (NF_IP6_PRI_NAT_DST
+ 1).
Quoted 8 lines
I can see that the code path can be changed (with this patch), if a helper is assigned. Then the "replay" starts at prio -199 (
NF_IP6_PRI_CONNTRACK+ 1), I guess I'm safe as I run at -99.I have tested that your patchset works, with my ipvs patches, but would like the trigger the changed code path, to make sure.
Could you provide an iptables command/rule, that trigger this code path?
The easiest way is a large ping with the NAT patches also applied, in that case we also pass the first packet of a connection through the stack reassembled.
Quoted 23 lines
Quoted 23 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +9
-0@@ -199,9 +200,13 @@ static unsigned int ipv6_confirm(unsigned int hooknum,static unsigned int __ipv6_conntrack_in (struct net *net,unsigned int hooknum,struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out,int (*okfn)(struct sk_buff *)) {struct sk_buff *reasm = skb->nfct_reasm; +struct nf_conn *ct; +enum ip_conntrack_info ctinfo;/* This packet is fragmented and has reassembled packet. */ if (reasm) {@@ -213,6 +218,20 @@ static unsigned int __ipv6_conntrack_in(struct net *net,if (ret !=NF_ACCEPT )return ret; } + +/* Conntrack helpers need the entire reassembled packet in the +* POST_ROUTING hook. +*/ + ct =nf_ct_get (reasm, &ctinfo);
Quoted 8 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c static unsigned int __ipv6_conntrack_in(struct net *net, · line 231
Quoted 6 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +6
-0+if (ct !=NULL &&test_bit (IPS_HELPER_BIT , &ct->status)) { +nf_conntrack_get_reasm (skb); +NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, reasm, + (struct net_device *)in, + (struct net_device *)out, + okfn,NF_IP6_PRI_CONNTRACK +1 );Hook prio change to
NF_IP6_PRI_CONNTRACK+ 1
I didn't get this part, you want to change to PRE_CONNTRACK + 1? What about raw and SELinux?
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 31 lines · Patrick McHardy
Quoted 29 lines · Jesper Dangaard Brouer
Quoted 12 lines · On Thu, 2012-08-09 at 22:08 +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
The IPv6 conntrack fragmentation currently has a couple of shortcomings. Fragmentes are collected in PREROUTING/OUTPUT, are defragmented, the defragmented packet is then passed to conntrack, the resulting conntrack information is attached to each original fragment and the fragments then continue their way through the stack.
Helper invocation occurs in the POSTROUTING hook, at which point only the original fragments are available. The result of this is that fragmented packets are never passed to helpers.
Quoted 5 lines
This patch improves the situation in the following way:
- If a reassembled packet belongs to a connection that has a helper assigned, the reassembled packet is passed through the stack instead of the original fragments.
I'm working on IPv6 fragment handling for IPVS, and are taking advantage of the "replay" by
nf_ct_frag6_output()at hook prio -399 (NF_IP6_PRI_CONNTRACK_DEFRAG+ 1).
By making a hook atNF_INET_PRE_ROUTINGat prio -99 (NF_IP6_PRI_NAT_DST
+ 1).I can see that the code path can be changed (with this patch), if a helper is assigned. Then the "replay" starts at prio -199 (
NF_IP6_PRI_CONNTRACK+ 1), I guess I'm safe as I run at -99.
Quoted 8 lines
Quoted 4 lines
I have tested that your patchset works, with my ipvs patches, but would like the trigger the changed code path, to make sure.
Could you provide an iptables command/rule, that trigger this code path?
The easiest way is a large ping with the NAT patches also applied, in that case we also pass the first packet of a connection through the stack reassembled.
So, a fragmented IPv6 ICMPv6 packet, I assume?
Don't I need to load some of the helper modules, or just the nf_conntrack_ipv6 module, or perhaps only nf_defrag_ipv6 ?
Quoted 32 lines
Quoted 23 lines
Quoted 23 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +9
-0@@ -199,9 +200,13 @@ static unsigned int ipv6_confirm(unsigned int hooknum,static unsigned int __ipv6_conntrack_in (struct net *net,unsigned int hooknum,struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out,int (*okfn)(struct sk_buff *)) {struct sk_buff *reasm = skb->nfct_reasm; +struct nf_conn *ct; +enum ip_conntrack_info ctinfo;/* This packet is fragmented and has reassembled packet. */ if (reasm) {@@ -213,6 +218,20 @@ static unsigned int __ipv6_conntrack_in(struct net *net,if (ret !=NF_ACCEPT )return ret; } + +/* Conntrack helpers need the entire reassembled packet in the +* POST_ROUTING hook. +*/ + ct =nf_ct_get (reasm, &ctinfo);Quoted 8 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c static unsigned int __ipv6_conntrack_in(struct net *net, · line 231
Quoted 6 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +6
-0+if (ct !=NULL &&test_bit (IPS_HELPER_BIT , &ct->status)) { +nf_conntrack_get_reasm (skb); +NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, reasm, + (struct net_device *)in, + (struct net_device *)out, + okfn,NF_IP6_PRI_CONNTRACK +1 );Hook prio change to
NF_IP6_PRI_CONNTRACK+ 1
Quoted 2 lines
I didn't get this part, you want to change to
PRE_CONNTRACK+ 1? What about raw and SELinux?
No - I don't want any changes.
I was just pointing out *where* the changes occur in your patch. This is just a "service" to other email readers, so they can spot the changes faster, I were referring to.
Signature · 5 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Sr. Network Kernel Developer at Red Hat Author of http://www.iptv-analyzer.org LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 9 lines · Jesper Dangaard Brouer
Quoted 6 lines · Patrick McHardy
Quoted 2 lines
Could you provide an iptables command/rule, that trigger this code path?
The easiest way is a large ping with the NAT patches also applied, in that case we also pass the first packet of a connection through the stack reassembled.
So, a fragmented IPv6 ICMPv6 packet, I assume?
Correct.
Quoted 2 lines
Don't I need to load some of the helper modules, or just the
nf_conntrack_ipv6module, or perhaps onlynf_defrag_ipv6?
Not with the entire patchset, just IPv6 conntrack is enough. Aith IPv6 NAT the first packet of a connection must always be defragemented, independant of an assigned helper.
Quoted 32 lines
Quoted 32 lines
Quoted 31 lines
Quoted 19 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +5
-0@@ -199,9 +200,13 @@ static unsigned int ipv6_confirm(unsigned int hooknum,static unsigned int __ipv6_conntrack_in (struct net *net,unsigned int hooknum,struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out,int (*okfn)(struct sk_buff *)) {struct sk_buff *reasm = skb->nfct_reasm; +struct nf_conn *ct; +enum ip_conntrack_info ctinfo;/* This packet is fragmented and has reassembled packet. */ if (reasm) {@@ -213,6 +218,20 @@ static unsigned int __ipv6_conntrack_in(struct net *net,if (ret !=NF_ACCEPT )return ret; } +net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c static unsigned int __ipv6_conntrack_in(struct net *net, · line 231
Quoted 10 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +10
-0+/* Conntrack helpers need the entire reassembled packet in the +* POST_ROUTING hook. +*/ + ct =nf_ct_get (reasm, &ctinfo); +if (ct !=NULL &&test_bit (IPS_HELPER_BIT , &ct->status)) { +nf_conntrack_get_reasm (skb); +NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, reasm, + (struct net_device *)in, + (struct net_device *)out, + okfn,NF_IP6_PRI_CONNTRACK +1 );Hook prio change to
NF_IP6_PRI_CONNTRACK+ 1
Quoted 8 lines
Quoted 2 lines
I didn't get this part, you want to change to
PRE_CONNTRACK+ 1? What about raw and SELinux?No - I don't want any changes.
I was just pointing out *where* the changes occur in your patch. This is just a "service" to other email readers, so they can spot the changes faster, I were referring to.
Could you send me your patch so I get a better picture of what you're doing exactly?
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 2 lines · Patrick McHardy
Could you send me your patch so I get a better picture of what you're doing exactly?
Okay, just posted the patchset.
Specifically look at patch:
[PATCH 3/3] ipvs: Complete IPv6 fragment handling for IPVS
Where I use the hook to copy the fw mark from the reasm SKB packet to the SKB fragments. (Perhaps, this could be done else were in the netfilter framework).
--Jesper Brouer
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 5 lines · Jesper Dangaard Brouer
Quoted 2 lines · Patrick McHardy
Could you send me your patch so I get a better picture of what you're doing exactly?
Quoted 8 lines
Okay, just posted the patchset.
Specifically look at patch:
[PATCH 3/3] ipvs: Complete IPv6 fragment handling for IPVSWhere I use the hook to copy the fw mark from the reasm SKB packet to the SKB fragments. (Perhaps, this could be done else were in the netfilter framework).
Thanks, I'll have a look at this tommorrow.
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
In reply to Patrick McHardyQuoted 2 lines · Patrick McHardy
Quoted 1 line · Jesper Dangaard Brouer
On Sat, 2012-08-18 at 14:26 +0200, Patrick McHardy wrote:
[...]
Quoted 6 lines
Quoted 2 lines
Don't I need to load some of the helper modules, or just the
nf_conntrack_ipv6module, or perhaps onlynf_defrag_ipv6?Not with the entire patchset, just IPv6 conntrack is enough. Aith IPv6 NAT the first packet of a connection must always be defragemented, independant of an assigned helper.
When loading "nf_conntrack_ipv6" I run into issues.
When sending a fragmented UDP packet. With these patches, the IPVS stack will no longer see the fragmented packets, but instead see one large SKB. This will trigger a MTU path check in e.g. ip_vs_dr_xmit_v6() and an ICMPv6 too big packet is send back.
IPVS: ip_vs_dr_xmit_v6(): frag needed
Perhaps we could change/fix the MTU check in IPVS?
(This would also solve issues I've seen with TSO/GSO frames, hitting this code path).
Signature · 5 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Sr. Network Kernel Developer at Red Hat Author of http://www.iptv-analyzer.org LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 19 lines · Jesper Dangaard Brouer
Quoted 2 lines · Patrick McHardy
Quoted 1 line · Jesper Dangaard Brouer
On Sat, 2012-08-18 at 14:26 +0200, Patrick McHardy wrote:
[...]
Quoted 6 lines
Quoted 2 lines
Don't I need to load some of the helper modules, or just the
nf_conntrack_ipv6module, or perhaps onlynf_defrag_ipv6?Not with the entire patchset, just IPv6 conntrack is enough. Aith IPv6 NAT the first packet of a connection must always be defragemented, independant of an assigned helper.
When loading "
nf_conntrack_ipv6" I run into issues.When sending a fragmented UDP packet. With these patches, the IPVS stack will no longer see the fragmented packets, but instead see one large SKB. This will trigger a MTU path check in e.g.
ip_vs_dr_xmit_v6()and an ICMPv6 too big packet is send back.
Quoted 5 lines
IPVS:
ip_vs_dr_xmit_v6(): frag neededPerhaps we could change/fix the MTU check in IPVS?
(This would also solve issues I've seen with TSO/GSO frames, hitting this code path).
I guess this should use the same check as in IPv6 output, check whether IP6CB(skb)->max_frag_size is != 0 and > MTU and only send an ICMPv6 error in that case.
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 23 lines · Patrick McHardy
Quoted 21 lines · Jesper Dangaard Brouer
Quoted 2 lines · Patrick McHardy
Quoted 1 line · Jesper Dangaard Brouer
On Sat, 2012-08-18 at 14:26 +0200, Patrick McHardy wrote:
[...]
Quoted 6 lines
Quoted 2 lines
Don't I need to load some of the helper modules, or just the
nf_conntrack_ipv6module, or perhaps onlynf_defrag_ipv6?Not with the entire patchset, just IPv6 conntrack is enough. Aith IPv6 NAT the first packet of a connection must always be defragemented, independant of an assigned helper.
When loading "
nf_conntrack_ipv6" I run into issues.When sending a fragmented UDP packet. With these patches, the IPVS stack will no longer see the fragmented packets, but instead see one large SKB. This will trigger a MTU path check in e.g.
ip_vs_dr_xmit_v6()and an ICMPv6 too big packet is send back.IPVS:
ip_vs_dr_xmit_v6(): frag needed
Quoted 7 lines
Quoted 3 lines
Perhaps we could change/fix the MTU check in IPVS?
(This would also solve issues I've seen with TSO/GSO frames, hitting this code path).I guess this should use the same check as in IPv6 output, check whether IP6CB(skb)->max_frag_size is != 0 and > MTU and only send an ICMPv6 error in that case.
Hans have (already) proposed this solution:
if ((!skb->local_df && skb->len > mtu && !skb_is_gso(skb)) ||
(IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)) {And I have tested it works.
But I'm not sure about, if we really need the "!skb->local_df" check ?
Thus, we should extend you patchset with a patch, that also address the MTU checks in IPVS.
Signature · 5 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Sr. Network Kernel Developer at Red Hat Author of http://www.iptv-analyzer.org LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 17 lines · Jesper Dangaard Brouer
Quoted 9 lines
Quoted 9 lines
When loading "
nf_conntrack_ipv6" I run into issues.When sending a fragmented UDP packet. With these patches, the IPVS stack will no longer see the fragmented packets, but instead see one large SKB. This will trigger a MTU path check in e.g.
ip_vs_dr_xmit_v6()and an ICMPv6 too big packet is send back.IPVS:
ip_vs_dr_xmit_v6(): frag neededQuoted 7 lines
Quoted 3 lines
Perhaps we could change/fix the MTU check in IPVS?
(This would also solve issues I've seen with TSO/GSO frames, hitting this code path).I guess this should use the same check as in IPv6 output, check whether IP6CB(skb)->max_frag_size is != 0 and > MTU and only send an ICMPv6 error in that case.
Quoted 7 lines
Hans have (already) proposed this solution:
if ((!skb->local_df &&
skb->len> mtu && !skb_is_gso(skb)) ||(IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)) {And I have tested it works.
But I'm not sure about, if we really need the "!skb->local_df" check ?
Not necessarily, alternatively you could use:
if ((!IP6CB(skb)->frag_max_size &&
(skb->len > mtu && !skb_is_gso(skb)) ||
IP6CB(skb)->frag_max_size > mtu)We just need to make sure that if frag_max_size is set that skb->len is ignored. Either way is fine, but I'd suggest to keep it similar to the variant used in IPv6.
Quoted 2 lines
Thus, we should extend you patchset with a patch, that also address the MTU checks in IPVS.
Can you send over a patch for inclusion in the patchset? Besides this, its ready for submission.
cover net: ipvs and netfilter IPv6 defrag MTU handling
The following patchset makes IPVS compatible with Patrick McHardys IPv6 NAT patchset: http://thread.gmane.org/gmane.linux.network/239615
Specifically the part that improves defragmentation.
Patch01: Cleanup (and fixes a bug) in IPVS MTU IPv6 handling
Patch02: Extend MTU check to account for IPv6 NAT defrag changes
This patchset is based upon:
Homes ipvs-next tree:
git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next.git
BUT with Patrick McHardy's IPv6 NAT patchset applied first, on top of
commit: 3654e61137db891f5312e6dd813b961484b5fdf3
title: "ipvs: add pmtu_disc option to disable IP DF for TUN packets"
Send due to request by Patrick:
http://thread.gmane.org/gmane.linux.network/239615/focus=43870
---
Jesper Dangaard Brouer (2):
ipvs: Extend MTU check to account for IPv6 NAT defrag changes
ipvs: IPv6 MTU checking cleanup and bugfix
net/netfilter/ipvs/ip_vs_xmit.c | 32 ++++++++++++++++++++++++++------ 1 files changed, 26 insertions(+), 6 deletions(-)
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Sr. Network Kernel Developer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
PATCH 1/2 ipvs: IPv6 MTU checking cleanup and bugfix
Cleaning up the IPv6 MTU checking in the IPVS xmit code, by using a common helper function __mtu_check_toobig_v6(). The MTU check for tunnel mode is special, and does not use this helper.
Notice, this also fixes a bug, as the the MTU check in ip_vs_dr_xmit_v6() were missing a check for skb_is_gso().
This e.g. caused issues for KVM IPVS setups, where different Segmentation Offloading techniques are utilized, between guests, via the virtio driver. This resulted in very bad performance, due to the ICMPv6 "too big" messages didn't affect the sender.
---
net/netfilter/ipvs/ip_vs_xmit.c | 18 ++++++++++++++---- 1 files changed, 14 insertions(+), 4 deletions(-)
net/netfilter/ipvs/ip_vs_xmit.c +14 -4
@@ -85,6 +85,15 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)return dst; } +static inline bool +__mtu_check_toobig_v6 (const struct sk_buff *skb,u32 mtu) +{ +if (skb->len > mtu && !skb_is_gso (skb)) { +return true;/* Packet size violate MTU size */ + } +return false; +} +/* Get route to daddr, update *saddr, optionally bind route to saddr */ static struct rtable *do_output_route4 (struct net *net,__be32 daddr,u32 rtos,int rt_mode,__be32 *saddr)
@@ -491,7 +500,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,/* MTU checking */ mtu =dst_mtu (&rt->dst); -if (skb->len > mtu && !skb_is_gso (skb)) { +if (__mtu_check_toobig_v6 (skb, mtu)) {if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
@@ -712,7 +721,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,/* MTU checking */ mtu =dst_mtu (&rt->dst); -if (skb->len > mtu && !skb_is_gso (skb)) { +if (__mtu_check_toobig_v6 (skb, mtu)) {if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
@@ -946,6 +955,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,if (skb_dst (skb))skb_dst (skb)->ops->update_pmtu (skb_dst (skb),NULL , skb, mtu); +/* MTU checking: Special for tunnel mode */ if (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && !skb_is_gso (skb)) {if (!skb->dev) {
@@ -1113,7 +1123,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,/* MTU checking */ mtu =dst_mtu (&rt->dst); -if (skb->len > mtu) { +if (__mtu_check_toobig_v6 (skb, mtu)) {if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
@@ -1349,7 +1359,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,/* MTU checking */ mtu =dst_mtu (&rt->dst); -if (skb->len > mtu && !skb_is_gso (skb)) { +if (__mtu_check_toobig_v6 (skb, mtu)) {if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
PATCH 2/2 ipvs: Extend MTU check to account for IPv6 NAT defrag changes
In reply to Jesper Dangaard BrouerThis patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
---
I would appriciate, if someone (e.g. Julian) double check the tunnel mode code. --Jesper
net/netfilter/ipvs/ip_vs_xmit.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-)
net/netfilter/ipvs/ip_vs_xmit.c +13 -3
@@ -88,7 +88,14 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)static inline bool __mtu_check_toobig_v6 (const struct sk_buff *skb,u32 mtu) { -if (skb->len > mtu && !skb_is_gso (skb)) { +if (IP6CB (skb)->frag_max_size) { +/* frag_max_size tell us that, this packet have been +* defragmented by netfilter IPv6 conntrack module. +*/ +if (IP6CB (skb)->frag_max_size > mtu) +return true;/* largest fragment violate MTU */ + } +else if (skb->len > mtu && !skb_is_gso (skb)) {return true;/* Packet size violate MTU size */ }return false;
@@ -956,8 +963,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,skb_dst (skb)->ops->update_pmtu (skb_dst (skb),NULL , skb, mtu);/* MTU checking: Special for tunnel mode */ -if (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && - !skb_is_gso (skb)) { +if ((!IP6CB (skb)->frag_max_size && + (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && + !skb_is_gso (skb))) + ||IP6CB (skb)->frag_max_size +sizeof (struct ipv6hdr ) > mtu) { +if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
Julian Anastasov
maintainerRe: [PATCH 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
Hello,
Quoted 7 lines · Jesper Dangaard Brouer
This patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
Signed-off-by Jesper Dangaard Brouer <[email protected]>---
I would appriciate, if someone (e.g. Julian) double check the tunnel mode code.
Sure
Quoted 6 lines
--Jesper
net/netfilter/ipvs/ip_vs_xmit.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-)
net/netfilter/ipvs/ip_vs_xmit.c ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, · line 970
Quoted 10 lines
net/netfilter/ipvs/ip_vs_xmit.c +5
-2@@ -956,8 +963,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,skb_dst (skb)->ops->update_pmtu (skb_dst (skb),NULL , skb, mtu);/* MTU checking: Special for tunnel mode */ -if (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && - !skb_is_gso (skb)) { +if ((!IP6CB (skb)->frag_max_size && + (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && + !skb_is_gso (skb))) + ||IP6CB (skb)->frag_max_size +sizeof (struct ipv6hdr ) > mtu) { +
mtu is already reduced with the new outer header size,
may be we can just call __mtu_check_toobig_v6 with mtu?
net/netfilter/ipvs/ip_vs_xmit.c ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, · line 972
Quoted 2 lines
net/netfilter/ipvs/ip_vs_xmit.c +0
-0if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
All other changes in patch 1 and 2 look ok and
I'll ack them next time.
Regards
--
Julian Anastasov <[email protected]>
Re: [PATCH 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
Quoted 35 lines · Julian Anastasov
Hello,
Quoted 7 lines · Jesper Dangaard Brouer
This patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
Signed-off-by Jesper Dangaard Brouer <[email protected]>---
I would appriciate, if someone (e.g. Julian) double check the tunnel mode code.
Sure
Quoted 6 lines
--Jesper
net/netfilter/ipvs/ip_vs_xmit.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-)net/netfilter/ipvs/ip_vs_xmit.c ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, · line 970
Quoted 10 lines
net/netfilter/ipvs/ip_vs_xmit.c +5
-2@@ -956,8 +963,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,skb_dst (skb)->ops->update_pmtu (skb_dst (skb),NULL , skb, mtu);/* MTU checking: Special for tunnel mode */ -if (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && - !skb_is_gso (skb)) { +if ((!IP6CB (skb)->frag_max_size && + (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && + !skb_is_gso (skb))) + ||IP6CB (skb)->frag_max_size +sizeof (struct ipv6hdr ) > mtu) { +mtu is already reduced with the new outer header size,
may be we can just call__mtu_check_toobig_v6with mtu?
Quoted 5 lines
net/netfilter/ipvs/ip_vs_xmit.c ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, · line 972
Quoted 2 lines
net/netfilter/ipvs/ip_vs_xmit.c +0
-0if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);All other changes in patch 1 and 2 look ok and
I'll ack them next time.
I'd like to take the final patches through my nat-ipv6 tree in order to avoid temporary regressions. Please let me know when they're ready for applying.
Simon Horman
maintainerRe: [PATCH 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
Quoted 40 lines · Patrick McHardy
Quoted 38 lines · Julian Anastasov
Hello,
Quoted 7 lines · Jesper Dangaard Brouer
This patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
Signed-off-by Jesper Dangaard Brouer <[email protected]>---
I would appriciate, if someone (e.g. Julian) double check the tunnel mode code.
Sure
Quoted 6 lines
--Jesper
net/netfilter/ipvs/ip_vs_xmit.c| 16 +++++++++++++---1 files changed, 13 insertions(+), 3 deletions(-)net/netfilter/ipvs/ip_vs_xmit.c ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, · line 970
Quoted 10 lines
net/netfilter/ipvs/ip_vs_xmit.c +5
-2@@ -956,8 +963,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,skb_dst (skb)->ops->update_pmtu (skb_dst (skb),NULL , skb, mtu);/* MTU checking: Special for tunnel mode */ -if (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && - !skb_is_gso (skb)) { +if ((!IP6CB (skb)->frag_max_size && + (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && + !skb_is_gso (skb))) + ||IP6CB (skb)->frag_max_size +sizeof (struct ipv6hdr ) > mtu) { +mtu is already reduced with the new outer header size,
may be we can just call__mtu_check_toobig_v6with mtu?Quoted 2 lines
net/netfilter/ipvs/ip_vs_xmit.c +0
-0if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
Quoted 6 lines
Quoted 2 lines
All other changes in patch 1 and 2 look ok and
I'll ack them next time.I'd like to take the final patches through my nat-ipv6 tree in order to avoid temporary regressions. Please let me know when they're ready for applying.
I'm fine with these changes going through your tree (rather than my IPVS tree) once they are ready.
v2 cover net: ipvs and netfilter IPv6 defrag MTU handling
In reply to Patrick McHardyThe following patchset V2 makes IPVS compatible with Patrick McHardys IPv6 NAT patchset: http://thread.gmane.org/gmane.linux.network/239615
Specifically the part that improves defragmentation.
Patch01: Cleanup (and fixes a bug) in IPVS MTU IPv6 handling
In V2: we also handle tunnel mode, to use the common helper
Patch02: Extend MTU check to account for IPv6 NAT defrag changes
In V2: the tunnel mode is no longer a special case.
This patchset is based upon:
Homes ipvs-next tree:
git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next.git
BUT with Patrick McHardy's IPv6 NAT patchset applied first, on top of
commit: 3654e61137db891f5312e6dd813b961484b5fdf3
title: "ipvs: add pmtu_disc option to disable IP DF for TUN packets"
---
Jesper Dangaard Brouer (2):
ipvs: Extend MTU check to account for IPv6 NAT defrag changes
ipvs: IPv6 MTU checking cleanup and bugfix
net/netfilter/ipvs/ip_vs_xmit.c | 28 ++++++++++++++++++++++------ 1 files changed, 22 insertions(+), 6 deletions(-)
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Sr. Network Kernel Developer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
PATCH v2 1/2 ipvs: IPv6 MTU checking cleanup and bugfix
Cleaning up the IPv6 MTU checking in the IPVS xmit code, by using a common helper function __mtu_check_toobig_v6().
The MTU check for tunnel mode can also use this helper as ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr) is qual to skb->len. And the 'mtu' variable have been adjusted before calling helper.
Notice, this also fixes a bug, as the the MTU check in ip_vs_dr_xmit_v6() were missing a check for skb_is_gso().
This bug e.g. caused issues for KVM IPVS setups, where different Segmentation Offloading techniques are utilized, between guests, via the virtio driver. This resulted in very bad performance, due to the ICMPv6 "too big" messages didn't affect the sender.
---
In V2: we also make tunnel mode use the common helper
net/netfilter/ipvs/ip_vs_xmit.c | 21 +++++++++++++++------ 1 files changed, 15 insertions(+), 6 deletions(-)
net/netfilter/ipvs/ip_vs_xmit.c +15 -6
@@ -85,6 +85,15 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)return dst; } +static inline bool +__mtu_check_toobig_v6 (const struct sk_buff *skb,u32 mtu) +{ +if (skb->len > mtu && !skb_is_gso (skb)) { +return true;/* Packet size violate MTU size */ + } +return false; +} +/* Get route to daddr, update *saddr, optionally bind route to saddr */ static struct rtable *do_output_route4 (struct net *net,__be32 daddr,u32 rtos,int rt_mode,__be32 *saddr)
@@ -491,7 +500,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,/* MTU checking */ mtu =dst_mtu (&rt->dst); -if (skb->len > mtu && !skb_is_gso (skb)) { +if (__mtu_check_toobig_v6 (skb, mtu)) {if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
@@ -712,7 +721,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,/* MTU checking */ mtu =dst_mtu (&rt->dst); -if (skb->len > mtu && !skb_is_gso (skb)) { +if (__mtu_check_toobig_v6 (skb, mtu)) {if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
@@ -946,8 +955,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,if (skb_dst (skb))skb_dst (skb)->ops->update_pmtu (skb_dst (skb),NULL , skb, mtu); -if (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && - !skb_is_gso (skb)) { +/* MTU checking: Notice that 'mtu' have been adjusted before hand */ +if (__mtu_check_toobig_v6 (skb, mtu)) {if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
@@ -1113,7 +1122,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,/* MTU checking */ mtu =dst_mtu (&rt->dst); -if (skb->len > mtu) { +if (__mtu_check_toobig_v6 (skb, mtu)) {if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
@@ -1349,7 +1358,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,/* MTU checking */ mtu =dst_mtu (&rt->dst); -if (skb->len > mtu && !skb_is_gso (skb)) { +if (__mtu_check_toobig_v6 (skb, mtu)) {if (!skb->dev) {struct net *net =dev_net (skb_dst (skb)->dev);
Patrick McHardy
AppliedRe: [PATCH V2 1/2] ipvs: IPv6 MTU checking cleanup and bugfix
Quoted 11 lines · Jesper Dangaard Brouer
Cleaning up the IPv6 MTU checking in the IPVS xmit code, by using a common helper function
__mtu_check_toobig_v6().The MTU check for tunnel mode can also use this helper as
ntohs(old_iph->payload_len)+ sizeof(struct ipv6hdr) is qual toskb->len. And the 'mtu' variable have been adjusted before calling helper.Notice, this also fixes a bug, as the the MTU check in
ip_vs_dr_xmit_v6()were missing a check forskb_is_gso().
Quoted 6 lines
This bug e.g. caused issues for KVM IPVS setups, where different Segmentation Offloading techniques are utilized, between guests, via the virtio driver. This resulted in very bad performance, due to the ICMPv6 "too big" messages didn't affect the sender.
Signed-off-by Jesper Dangaard Brouer <[email protected]>
Applied to my nf-nat-ipv6 tree.
PATCH v2 2/2 ipvs: Extend MTU check to account for IPv6 NAT defrag changes
In reply to Jesper Dangaard BrouerThis patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
---
In V2: the tunnel mode is no longer a special case.
net/netfilter/ipvs/ip_vs_xmit.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)
net/netfilter/ipvs/ip_vs_xmit.c +8 -1
@@ -88,7 +88,14 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)static inline bool __mtu_check_toobig_v6 (const struct sk_buff *skb,u32 mtu) { -if (skb->len > mtu && !skb_is_gso (skb)) { +if (IP6CB (skb)->frag_max_size) { +/* frag_max_size tell us that, this packet have been +* defragmented by netfilter IPv6 conntrack module. +*/ +if (IP6CB (skb)->frag_max_size > mtu) +return true;/* largest fragment violate MTU */ + } +else if (skb->len > mtu && !skb_is_gso (skb)) {return true;/* Packet size violate MTU size */ }return false;
Re: [PATCH V2 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
Quoted 19 lines · Jesper Dangaard Brouer
This patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
Signed-off-by Jesper Dangaard Brouer <[email protected]>---
In V2: the tunnel mode is no longer a special case.net/netfilter/ipvs/ip_vs_xmit.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)net/netfilter/ipvs/ip_vs_xmit.c +0
-1@@ -88,7 +88,14 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)static inline bool __mtu_check_toobig_v6 (const struct sk_buff *skb,u32 mtu) { -if (skb->len > mtu && !skb_is_gso (skb)) {
net/netfilter/ipvs/ip_vs_xmit.c __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) · line 100
Quoted 10 lines
net/netfilter/ipvs/ip_vs_xmit.c +8
-0+if (IP6CB (skb)->frag_max_size) { +/* frag_max_size tell us that, this packet have been +* defragmented by netfilter IPv6 conntrack module. +*/ +if (IP6CB (skb)->frag_max_size > mtu) +return true;/* largest fragment violate MTU */ + } +else if (skb->len > mtu && !skb_is_gso (skb)) {return true;/* Packet size violate MTU size */ }
Couldnt you use a single test ?
if (IP6CB(skb)->frag_max_size > mtu)
return true;
if (skb->len > mtu && !skb_is_gso(skb))
return true;
Re: [PATCH V2 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
Quoted 11 lines · Eric Dumazet
Quoted 10 lines · Jesper Dangaard Brouer
This patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
Signed-off-by Jesper Dangaard Brouer <[email protected]>---
In V2: the tunnel mode is no longer a special case.net/netfilter/ipvs/ip_vs_xmit.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)
Quoted 15 lines
Quoted 5 lines
net/netfilter/ipvs/ip_vs_xmit.c +0
-0net/netfilter/ipvs/ip_vs_xmit.c __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) · line 96
Quoted 10 lines
net/netfilter/ipvs/ip_vs_xmit.c +6
-1@@ -88,7 +88,14 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)static inline bool __mtu_check_toobig_v6 (const struct sk_buff *skb,u32 mtu) { -if (skb->len > mtu && !skb_is_gso (skb)) { +if (IP6CB (skb)->frag_max_size) { +/* frag_max_size tell us that, this packet have been +* defragmented by netfilter IPv6 conntrack module. +*/ +if (IP6CB (skb)->frag_max_size > mtu) +return true;/* largest fragment violate MTU */
Implicit: else
return false
(if it makes it more clear, not sure)
Quoted 7 lines
net/netfilter/ipvs/ip_vs_xmit.c __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) · line 100
Quoted 4 lines
net/netfilter/ipvs/ip_vs_xmit.c +2
-0+ } +else if (skb->len > mtu && !skb_is_gso (skb)) {return true;/* Packet size violate MTU size */ }Couldnt you use a single test ?
Quoted 6 lines
if (IP6CB(skb)->frag_max_size > mtu)
return true;if (
skb->len> mtu && !skb_is_gso(skb))return true;
Nope, this will not work.
If (IP6CB(skb)->frag_max_size > 0) then we have a defragmented packet, this means that skb->len cannot be used for MTU checking, because skb->len is now the total length of all the fragments (which your solution will fall-through to)
The unreadable version of the function is:
static inline bool__mtu_check_toobig_v6_unreadable(const struct sk_buff *skb, u32 mtu)
{
return !!((!IP6CB(skb)->frag_max_size &&
(skb->len > mtu && !skb_is_gso(skb)))
|| IP6CB(skb)->frag_max_size > mtu);
}Perhaps you like this version better (you seem to use constructions like this), but I really dislike it, because I (personally) find it harder/slower to read this kind of code, and I also believe its more error prone when someone needs to extend this.
Signature · 5 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Sr. Network Kernel Developer at Red Hat Author of http://www.iptv-analyzer.org LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH V2 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
Quoted 45 lines · Jesper Dangaard Brouer
Quoted 11 lines · Eric Dumazet
Quoted 10 lines · Jesper Dangaard Brouer
This patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
Signed-off-by Jesper Dangaard Brouer <[email protected]>---
In V2: the tunnel mode is no longer a special case.net/netfilter/ipvs/ip_vs_xmit.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)Quoted 15 lines
Quoted 5 lines
net/netfilter/ipvs/ip_vs_xmit.c +0
-0net/netfilter/ipvs/ip_vs_xmit.c __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) · line 96
Quoted 10 lines
net/netfilter/ipvs/ip_vs_xmit.c +6
-1@@ -88,7 +88,14 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)static inline bool __mtu_check_toobig_v6 (const struct sk_buff *skb,u32 mtu) { -if (skb->len > mtu && !skb_is_gso (skb)) { +if (IP6CB (skb)->frag_max_size) { +/* frag_max_size tell us that, this packet have been +* defragmented by netfilter IPv6 conntrack module. +*/ +if (IP6CB (skb)->frag_max_size > mtu) +return true;/* largest fragment violate MTU */ Implicit: else
return false(if it makes it more clear, not sure)
Quoted 7 lines
net/netfilter/ipvs/ip_vs_xmit.c __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) · line 100
Quoted 4 lines
net/netfilter/ipvs/ip_vs_xmit.c +2
-0+ } +else if (skb->len > mtu && !skb_is_gso (skb)) {return true;/* Packet size violate MTU size */ }Couldnt you use a single test ?
Quoted 6 lines
if (IP6CB(skb)->frag_max_size > mtu)
return true;if (
skb->len> mtu && !skb_is_gso(skb))return true;
Quoted 7 lines
Nope, this will not work.
If (IP6CB(skb)->frag_max_size > 0) then we have a defragmented packet, this means that
skb->lencannot be used for MTU checking, becauseskb->lenis now the total length of all the fragments (which your solution will fall-through to)
If the packet was not fragmented, its was a single frame.
But if this frame length is above mtu, packet is not too big ?
Sorry if its a stupid question.
Re: [PATCH V2 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
Quoted 54 lines · Eric Dumazet
Quoted 45 lines · Jesper Dangaard Brouer
Quoted 11 lines · Eric Dumazet
Quoted 10 lines · Jesper Dangaard Brouer
This patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
Signed-off-by Jesper Dangaard Brouer <[email protected]>---
In V2: the tunnel mode is no longer a special case.net/netfilter/ipvs/ip_vs_xmit.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)Quoted 15 lines
Quoted 5 lines
net/netfilter/ipvs/ip_vs_xmit.c +0
-0net/netfilter/ipvs/ip_vs_xmit.c __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) · line 96
Quoted 10 lines
net/netfilter/ipvs/ip_vs_xmit.c +6
-1@@ -88,7 +88,14 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)static inline bool __mtu_check_toobig_v6 (const struct sk_buff *skb,u32 mtu) { -if (skb->len > mtu && !skb_is_gso (skb)) { +if (IP6CB (skb)->frag_max_size) { +/* frag_max_size tell us that, this packet have been +* defragmented by netfilter IPv6 conntrack module. +*/ +if (IP6CB (skb)->frag_max_size > mtu) +return true;/* largest fragment violate MTU */ Implicit: else
return false(if it makes it more clear, not sure)
Quoted 7 lines
net/netfilter/ipvs/ip_vs_xmit.c __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) · line 100
Quoted 4 lines
net/netfilter/ipvs/ip_vs_xmit.c +2
-0+ } +else if (skb->len > mtu && !skb_is_gso (skb)) {return true;/* Packet size violate MTU size */ }Couldnt you use a single test ?
Quoted 6 lines
if (IP6CB(skb)->frag_max_size > mtu)
return true;if (
skb->len> mtu && !skb_is_gso(skb))return true;Quoted 7 lines
Nope, this will not work.
If (IP6CB(skb)->frag_max_size > 0) then we have a defragmented packet, this means that
skb->lencannot be used for MTU checking, becauseskb->lenis now the total length of all the fragments (which your solution will fall-through to)
Quoted 3 lines
If the packet was not fragmented, its was a single frame.
But if this frame length is above mtu, packet is not too big ?
Nope... not if its a defragmented/reassembled packet.
Quoted 1 line
Sorry if its a stupid question.
These changes have to be seen together with Patrick's patch:
"netfilter: nf_conntrack_ipv6: improve fragmentation handling"
http://thread.gmane.org/gmane.linux.network/241517/focus=241518
The IPv6 packet arriving have been defragmented/reassembled by the nf_conntrack_ipv6 module. Thus, they look like a normal, but big,
packet to us. We let it through, because it will be re-fragmented
again later, but first we need to check if the largest fragment would violate the MTU.
Hope it makes it more clear.
Re: [PATCH V2 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
In reply to Jesper Dangaard BrouerQuoted 4 lines · Jesper Dangaard Brouer
This patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
Signed-off-by Jesper Dangaard Brouer <[email protected]>
I've folded this into the defragmentation patch to avoid temporary breakage. Thanks Jesper.
Re: [PATCH 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
In reply to Julian AnastasovQuoted 16 lines · Julian Anastasov
Hello,
Quoted 7 lines · Jesper Dangaard Brouer
This patch is necessary, to make IPVS work, after Patrick McHardys IPv6 NAT defragmentation changes.
Signed-off-by Jesper Dangaard Brouer <[email protected]>---
I would appriciate, if someone (e.g. Julian) double check the tunnel mode code.
Sure
Quoted 2 lines
--Jesper
Quoted 8 lines
net/netfilter/ipvs/ip_vs_xmit.c ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, · line 959
Quoted 8 lines
net/netfilter/ipvs/ip_vs_xmit.c | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-)net/netfilter/ipvs/ip_vs_xmit.c +0
-1@@ -956,8 +963,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,skb_dst (skb)->ops->update_pmtu (skb_dst (skb),NULL , skb, mtu);/* MTU checking: Special for tunnel mode */ - if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr) &&
I guess:
ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)
Is the same as:
skb->len
Quoted 9 lines
net/netfilter/ipvs/ip_vs_xmit.c ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, · line 969
Quoted 5 lines
net/netfilter/ipvs/ip_vs_xmit.c +4
-1- !skb_is_gso(skb)) { +if ((!IP6CB (skb)->frag_max_size && + (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && + !skb_is_gso (skb))) + ||IP6CB (skb)->frag_max_size +sizeof (struct ipv6hdr ) > mtu) {mtu is already reduced with the new outer header size,
may be we can just call__mtu_check_toobig_v6with mtu?
To Julian, is the extra sizeof(struct ipv6hdr) addition to frag_max_size, wrong? (as the mtu is already reduced)
If above statements hold, I think we can simply use __mtu_check_toobig_v6() also for the tunnel case :-)
--Jesper
Julian Anastasov
maintainerRe: [PATCH 2/2] ipvs: Extend MTU check to account for IPv6 NAT defrag changes
Hello,
Quoted 5 lines · Jesper Dangaard Brouer
Quoted 4 lines · Julian Anastasov
Quoted 4 lines
net/netfilter/ipvs/ip_vs_xmit.c +0
-0@@ -956,8 +963,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,skb_dst (skb)->ops->update_pmtu (skb_dst (skb),NULL , skb, mtu);
Quoted 7 lines
Quoted 2 lines
net/netfilter/ipvs/ip_vs_xmit.c ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, · line 959
Quoted 2 lines
net/netfilter/ipvs/ip_vs_xmit.c +0
-1/* MTU checking: Special for tunnel mode */ - if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr) &&I guess:
ntohs(old_iph->payload_len)+ sizeof(struct ipv6hdr)
Is the same as:
skb->len
I think so. You can think of this in different way:
all transmitters are called from same place, there is no difference in the packets we see. When we can use __mtu_check_toobig_v6 for other methods relying on skb->len being correct, we can do the same for tunnels, only that tunnels have lower MTU, that is the only difference.
Quoted 10 lines
Quoted 9 lines
net/netfilter/ipvs/ip_vs_xmit.c ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, · line 969
Quoted 5 lines
net/netfilter/ipvs/ip_vs_xmit.c +4
-1- !skb_is_gso(skb)) { +if ((!IP6CB (skb)->frag_max_size && + (mtu <ntohs (old_iph->payload_len) +sizeof (struct ipv6hdr ) && + !skb_is_gso (skb))) + ||IP6CB (skb)->frag_max_size +sizeof (struct ipv6hdr ) > mtu) {mtu is already reduced with the new outer header size,
may be we can just call__mtu_check_toobig_v6with mtu?
Quoted 2 lines
To Julian, is the extra sizeof(struct ipv6hdr) addition to
frag_max_size, wrong? (as the mtu is already reduced)
Yes, sizeof(struct ipv6hdr) is needed only together
with payload_len because payload_len does not include the first header.
Quoted 2 lines
If above statements hold, I think we can simply use
__mtu_check_toobig_v6()also for the tunnel case :-)
Yep
Quoted 1 line
--Jesper
Regards
--
Julian Anastasov <[email protected]>
Pablo Neira Ayuso
maintainerRe: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
In reply to [email protected]Quoted 133 lines · On Thu, Aug 09, 2012 at 10:08:49PM +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
The IPv6 conntrack fragmentation currently has a couple of shortcomings. Fragmentes are collected in PREROUTING/OUTPUT, are defragmented, the defragmented packet is then passed to conntrack, the resulting conntrack information is attached to each original fragment and the fragments then continue their way through the stack.
Helper invocation occurs in the POSTROUTING hook, at which point only the original fragments are available. The result of this is that fragmented packets are never passed to helpers.
This patch improves the situation in the following way:
- If a reassembled packet belongs to a connection that has a helper assigned, the reassembled packet is passed through the stack instead of the original fragments.
- During defragmentation, the largest received fragment size is stored. On output, the packet is refragmented if required. If the largest received fragment size exceeds the outgoing MTU, a "packet too big" message is generated, thus behaving as if the original fragments were passed through the stack from an outside point of view.
- The
ipv6_helper()hook function can't receive fragments anymore for connections using a helper, so it is switched to useipv6_skip_exthdr()instead of the netfilter specificnf_ct_ipv6_skip_exthdr()and the reassembled packets are passed to connection tracking helpers.The result of this is that we can properly track fragmented packets, but still generate ICMPv6 Packet too big messages if we would have before.
This patch is also required as a precondition for IPv6 NAT, where NAT helpers might enlarge packets up to a point that they require fragmentation. In that case we can't generate Packet too big messages since the proper MTU can't be calculated in all cases (f.i. when changing textual representation of a variable amount of addresses), so the packet is transparently fragmented iff the original packet or fragments would have fit the outgoing MTU.
Signed-off-by Patrick McHardy <[email protected]>--- include/linux/ipv6.h | 1 + net/ipv6/ip6_output.c | 7 +++- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 37 ++++++++++++++++++------ net/ipv6/netfilter/nf_conntrack_reasm.c | 19 ++++++++++-- 4 files changed, 50 insertions(+), 14 deletions(-)include/linux/ipv6.h +1
-0@@ -256,6 +256,7 @@ struct inet6_skb_parm {#if defined(CONFIG_IPV6_MIP6 ) || defined(CONFIG_IPV6_MIP6_MODULE )__u16 dsthao;#endif +__u16 frag_max_size;#define IP6SKB_XFRM_TRANSFORMED 1#define IP6SKB_FORWARDED 2net/ipv6/ip6_output.c +5
-2@@ -493,7 +493,8 @@ int ip6_forward(struct sk_buff *skb)if (mtu <IPV6_MIN_MTU ) mtu =IPV6_MIN_MTU ; -if (skb->len > mtu && !skb_is_gso (skb)) { +if ((!skb->local_df && skb->len > mtu && !skb_is_gso (skb)) || + (IP6CB (skb)->frag_max_size &&IP6CB (skb)->frag_max_size > mtu)) {/* Again, force OUTPUT device used as source address */ skb->dev = dst->dev;icmpv6_send (skb,ICMPV6_PKT_TOOBIG ,0 , mtu);@@ -636,7 +637,9 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))/* We must not fragment if the socket is set to force MTU discovery * or if the skb it not generated by a local socket. */ -if (unlikely (!skb->local_df && skb->len > mtu)) { +if (unlikely (!skb->local_df && skb->len > mtu) || + (IP6CB (skb)->frag_max_size && +IP6CB (skb)->frag_max_size > mtu)) {if (skb->sk &&dst_allfrag (skb_dst (skb)))sk_nocaps_add (skb->sk,NETIF_F_GSO_MASK );net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +12
-7@@ -153,10 +153,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,const struct nf_conn_help *help;const struct nf_conntrack_helper *helper;enum ip_conntrack_info ctinfo; -unsigned int ret, protoff; -unsigned int extoff = (u8 *)(ipv6_hdr (skb) +1 ) - skb->data; -unsigned char pnum =ipv6_hdr (skb)->nexthdr; - +unsigned int ret; +__be16 frag_off; +int protoff; +u8 nexthdr;/* This is where we call the helper: as the packet goes out. */ ct =nf_ct_get (skb, &ctinfo);@@ -171,9 +171,10 @@ static unsigned int ipv6_helper(unsigned int hooknum,if (!helper)return NF_ACCEPT ; - protoff =nf_ct_ipv6_skip_exthdr (skb, extoff, &pnum, - skb->len - extoff); -if (protoff > skb->len || pnum ==NEXTHDR_FRAGMENT ) { + nexthdr =ipv6_hdr (skb)->nexthdr; + protoff =ipv6_skip_exthdr (skb,sizeof (struct ipv6hdr ), &nexthdr, + &frag_off); +if (protoff <0 || (frag_off &ntohs (~0x7 )) !=0 ) {pr_debug ("proto header not found\n" );return NF_ACCEPT ; }@@ -199,9 +200,13 @@ static unsigned int ipv6_confirm(unsigned int hooknum,static unsigned int __ipv6_conntrack_in (struct net *net,unsigned int hooknum,struct sk_buff *skb, +const struct net_device *in, +const struct net_device *out,int (*okfn)(struct sk_buff *)) {struct sk_buff *reasm = skb->nfct_reasm; +struct nf_conn *ct; +enum ip_conntrack_info ctinfo;/* This packet is fragmented and has reassembled packet. */ if (reasm) {
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c static unsigned int __ipv6_conntrack_in(struct net *net, · line 226
Quoted 9 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +6
-0@@ -213,6 +218,20 @@ static unsigned int __ipv6_conntrack_in(struct net *net,if (ret !=NF_ACCEPT )return ret; } + +/* Conntrack helpers need the entire reassembled packet in the +* POST_ROUTING hook. +*/ + ct =nf_ct_get (reasm, &ctinfo); +if (ct !=NULL &&test_bit (IPS_HELPER_BIT , &ct->status)) {
Two things regarding the line above:
- I think this also need to check for !nf_ct_is_untracked(ct)
- IPS_HELPER_BIT is only set if the CT target is used to attach helpers. I know, this behaviour may seem confusing, but I didn't find any better way to avoid that NAT removes the helper explicitly attached via CT.
So basically now that status bit means: "this helper has been attached via CT".
Setting it inconditionally in __nf_ct_try_assign_helper would break the magic auto-assign helper code.
On the other hand, the automatic helper assignment is scheduled to be removed (well, it would still take at least one 1.5/2 years before we do so). At that time, we'll be able to say that all conntrack with IPS_HELPER really has one helper. But now I think that you'll have to use for nfct_help instead to check if that ct has a helper.
Quoted 106 lines
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +10
-2+nf_conntrack_get_reasm (skb); +NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, reasm, + (struct net_device *)in, + (struct net_device *)out, + okfn,NF_IP6_PRI_CONNTRACK +1 ); +return NF_DROP_ERR (-ECANCELED ); + } +nf_conntrack_get (reasm->nfct); skb->nfct = reasm->nfct; skb->nfctinfo = reasm->nfctinfo;@@ -228,7 +247,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum, const struct net_device *out, int (*okfn)(struct sk_buff *)) { - return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn); + return __ipv6_conntrack_in(dev_net(in), hooknum, skb, in, out, okfn); } static unsigned int ipv6_conntrack_local(unsigned int hooknum,@@ -242,7 +261,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,net_notice_ratelimited ("ipv6_conntrack_local: packet too short\n" );return NF_ACCEPT ; } -return __ipv6_conntrack_in (dev_net (out), hooknum, skb, okfn); +return __ipv6_conntrack_in (dev_net (out), hooknum, skb, in, out, okfn); }static struct nf_hook_ops ipv6_conntrack_ops[]__read_mostly = {net/ipv6/netfilter/nf_conntrack_reasm.c +16
-3@@ -190,6 +190,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, const struct frag_hdr *fhdr, int nhoff) {struct sk_buff *prev, *next; +unsigned int payload_len;int offset, end;if (fq->q.last_in &INET_FRAG_COMPLETE ) {@@ -197,8 +198,10 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, goto err; } + payload_len =ntohs (ipv6_hdr (skb)->payload_len); + offset =ntohs (fhdr->frag_off) & ~0x7 ; - end = offset + (ntohs (ipv6_hdr (skb)->payload_len) - + end = offset + (payload_len - ((u8 *)(fhdr +1 ) - (u8 *)(ipv6_hdr (skb) +1 )));if ((unsigned int )end >IPV6_MAXPLEN ) {@@ -307,6 +310,8 @@ found: skb->dev =NULL ; fq->q.stamp = skb->tstamp; fq->q.meat += skb->len; +if (payload_len > fq->q.max_size) + fq->q.max_size = payload_len;atomic_add (skb->truesize, &nf_init_frags.mem);/* The first fragment. @@ -412,10 +417,12 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) }atomic_sub (head->truesize, &nf_init_frags.mem); + head->local_df =1 ; head->next =NULL ; head->dev = dev; head->tstamp = fq->q.stamp;ipv6_hdr (head)->payload_len =htons (payload_len); +IP6CB (head)->frag_max_size =sizeof (struct ipv6hdr ) + fq->q.max_size;/* Yes, and fold redundant checksum back. 8) */ if (head->ip_summed ==CHECKSUM_COMPLETE )@@ -592,6 +599,7 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, int (*okfn)(struct sk_buff *)) {struct sk_buff *s, *s2; +unsigned int ret =0 ;for (s =NFCT_FRAG6_CB (skb)->orig; s;) {nf_conntrack_put_reasm (s->nfct_reasm);@@ -601,8 +609,13 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, s2 = s->next; s->next =NULL ; -NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, s, in, out, okfn, -NF_IP6_PRI_CONNTRACK_DEFRAG +1 ); +if (ret != -ECANCELED ) + ret =NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, s, + in, out, okfn, +NF_IP6_PRI_CONNTRACK_DEFRAG +1 ); +else +kfree_skb (s); + s = s2; }nf_conntrack_put_reasm (skb);Signature · 6 lines
1.7.1 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 05/19] netfilter: nf_conntrack_ipv6: improve fragmentation handling
Quoted 11 lines · Pablo Neira Ayuso
Review
Quoted 6 lines · On Thu, Aug 09, 2012 at 10:08:49PM +0200, [email protected] wrote:
(quoted diff) +6
-0+ + /* Conntrack helpers need the entire reassembled packet in the + * POST_ROUTING hook. + */ + ct = nf_ct_get(reasm, &ctinfo); + if (ct != NULL && test_bit(IPS_HELPER_BIT, &ct->status)) {Two things regarding the line above:
- I think this also need to check for !nf_ct_is_untracked(ct)
Fixed, thanks.
Quoted 12 lines
-
IPS_HELPER_BITis only set if the CT target is used to attach helpers. I know, this behaviour may seem confusing, but I didn't find any better way to avoid that NAT removes the helper explicitly attached via CT.So basically now that status bit means: "this helper has been attached via CT".
Setting it inconditionally in
__nf_ct_try_assign_helperwould break the magic auto-assign helper code.
Quoted 6 lines
On the other hand, the automatic helper assignment is scheduled to be removed (well, it would still take at least one 1.5/2 years before we do so). At that time, we'll be able to say that all conntrack with
IPS_HELPERreally has one helper. But now I think that you'll have to use fornfct_helpinstead to check if that ct has a helper.
I see. Also fixed, thanks. New patch attached.
commit f4266409e20dc0d2d22447aa7935c997f38914a1
Author: Patrick McHardy <[email protected]> Date: Tue Aug 14 15:27:55 2012 +0200
netfilter: nf_conntrack_ipv6: improve fragmentation handling
The IPv6 conntrack fragmentation currently has a couple of shortcomings. Fragmentes are collected in PREROUTING/OUTPUT, are defragmented, the defragmented packet is then passed to conntrack, the resulting conntrack information is attached to each original fragment and the fragments then continue their way through the stack.
Helper invocation occurs in the POSTROUTING hook, at which point only the original fragments are available. The result of this is that fragmented packets are never passed to helpers.
This patch improves the situation in the following way:
- If a reassembled packet belongs to a connection that has a helper assigned, the reassembled packet is passed through the stack instead of the original fragments.
- During defragmentation, the largest received fragment size is stored. On output, the packet is refragmented if required. If the largest received fragment size exceeds the outgoing MTU, a "packet too big" message is generated, thus behaving as if the original fragments were passed through the stack from an outside point of view.
- The ipv6_helper() hook function can't receive fragments anymore for connections using a helper, so it is switched to use ipv6_skip_exthdr() instead of the netfilter specific nf_ct_ipv6_skip_exthdr() and the reassembled packets are passed to connection tracking helpers.
The result of this is that we can properly track fragmented packets, but still generate ICMPv6 Packet too big messages if we would have before.
This patch is also required as a precondition for IPv6 NAT, where NAT helpers might enlarge packets up to a point that they require fragmentation. In that case we can't generate Packet too big messages since the proper MTU can't be calculated in all cases (f.i. when changing textual representation of a variable amount of addresses), so the packet is transparently fragmented iff the original packet or fragments would have fit the outgoing MTU.
include/linux/ipv6.h +1 -0
@@ -256,6 +256,7 @@ struct inet6_skb_parm {#if defined(CONFIG_IPV6_MIP6 ) || defined(CONFIG_IPV6_MIP6_MODULE )__u16 dsthao;#endif +__u16 frag_max_size;#define IP6SKB_XFRM_TRANSFORMED 1#define IP6SKB_FORWARDED 2
net/ipv6/ip6_output.c +5 -2
@@ -493,7 +493,8 @@ int ip6_forward(struct sk_buff *skb)if (mtu <IPV6_MIN_MTU ) mtu =IPV6_MIN_MTU ; -if (skb->len > mtu && !skb_is_gso (skb)) { +if ((!skb->local_df && skb->len > mtu && !skb_is_gso (skb)) || + (IP6CB (skb)->frag_max_size &&IP6CB (skb)->frag_max_size > mtu)) {/* Again, force OUTPUT device used as source address */ skb->dev = dst->dev;icmpv6_send (skb,ICMPV6_PKT_TOOBIG ,0 , mtu);
@@ -636,7 +637,9 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))/* We must not fragment if the socket is set to force MTU discovery * or if the skb it not generated by a local socket. */ -if (unlikely (!skb->local_df && skb->len > mtu)) { +if (unlikely (!skb->local_df && skb->len > mtu) || + (IP6CB (skb)->frag_max_size && +IP6CB (skb)->frag_max_size > mtu)) {if (skb->sk &&dst_allfrag (skb_dst (skb)))sk_nocaps_add (skb->sk,NETIF_F_GSO_MASK );
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +32 -9
80 lines not on this page · raw message
net/ipv6/netfilter/nf_conntrack_reasm.c +16 -3
@@ -190,6 +190,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, const struct frag_hdr *fhdr, int nhoff) {struct sk_buff *prev, *next; +unsigned int payload_len;int offset, end;if (fq->q.last_in &INET_FRAG_COMPLETE ) {
@@ -197,8 +198,10 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, goto err; } + payload_len =ntohs (ipv6_hdr (skb)->payload_len); + offset =ntohs (fhdr->frag_off) & ~0x7 ; - end = offset + (ntohs (ipv6_hdr (skb)->payload_len) - + end = offset + (payload_len - ((u8 *)(fhdr +1 ) - (u8 *)(ipv6_hdr (skb) +1 )));if ((unsigned int )end >IPV6_MAXPLEN ) {
@@ -307,6 +310,8 @@ found: skb->dev =NULL ; fq->q.stamp = skb->tstamp; fq->q.meat += skb->len; +if (payload_len > fq->q.max_size) + fq->q.max_size = payload_len;atomic_add (skb->truesize, &nf_init_frags.mem);/* The first fragment.
@@ -412,10 +417,12 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) }atomic_sub (head->truesize, &nf_init_frags.mem); + head->local_df =1 ; head->next =NULL ; head->dev = dev; head->tstamp = fq->q.stamp;ipv6_hdr (head)->payload_len =htons (payload_len); +IP6CB (head)->frag_max_size =sizeof (struct ipv6hdr ) + fq->q.max_size;/* Yes, and fold redundant checksum back. 8) */ if (head->ip_summed ==CHECKSUM_COMPLETE )
@@ -592,6 +599,7 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, int (*okfn)(struct sk_buff *)) {struct sk_buff *s, *s2; +unsigned int ret =0 ;for (s =NFCT_FRAG6_CB (skb)->orig; s;) {nf_conntrack_put_reasm (s->nfct_reasm);
@@ -601,8 +609,13 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, s2 = s->next; s->next =NULL ; -NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, s, in, out, okfn, -NF_IP6_PRI_CONNTRACK_DEFRAG +1 ); +if (ret != -ECANCELED ) + ret =NF_HOOK_THRESH (NFPROTO_IPV6 , hooknum, s, + in, out, okfn, +NF_IP6_PRI_CONNTRACK_DEFRAG +1 ); +else +kfree_skb (s); + s = s2; }nf_conntrack_put_reasm (skb);
PATCH 6/19 netfilter: nf_conntrack_ipv6: fix tracking of ICMPv6 error messages containing fragments
In reply to [email protected]From: Patrick McHardy <[email protected]>
ICMPv6 error messages are tracked by extracting the conntrack tuple of the inner packet and looking up the corresponding conntrack entry. Tuple extraction uses the ->get_l4proto() callback, which in case of fragments returns NEXTHDR_FRAGMENT instead of the upper protocol, even for the first fragment when the entire next header is present, resulting in a failure to find the correct connection tracking entry.
This patch changes ipv6_get_l4proto() to use ipv6_skip_exthdr() instead of nf_ct_ipv6_skip_exthdr() in order to skip fragment headers when the fragment offset is zero.
--- net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 63 ++--------------------- 1 files changed, 6 insertions(+), 57 deletions(-)
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +6 -57
@@ -64,82 +64,31 @@ static int ipv6_print_tuple(struct seq_file *s, tuple->src.u3.ip6, tuple->dst.u3.ip6); } -/* -* Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c -* -* This function parses (probably truncated) exthdr set "hdr" -* of length "len". "nexthdrp" initially points to some place, -* where type of the first header can be found. -* -* It skips all well-known exthdrs, and returns pointer to the start -* of unparsable area i.e. the first header with unknown type. -* if success, *nexthdr is updated by type/protocol of this header. -* -* NOTES: - it may return pointer pointing beyond end of packet, -* if the last recognized header is truncated in the middle. -* - if packet is truncated, so that all parsed headers are skipped, -* it returns -1. -* - if packet is fragmented, return pointer of the fragment header. -* - ESP is unparsable for now and considered like -* normal payload protocol. -* - Note also special handling of AUTH header. Thanks to IPsec wizards. -*/ - -static int nf_ct_ipv6_skip_exthdr (const struct sk_buff *skb,int start, -u8 *nexthdrp,int len) -{ -u8 nexthdr = *nexthdrp; - -while (ipv6_ext_hdr (nexthdr)) { -struct ipv6_opt_hdr hdr; -int hdrlen; - -if (len < (int )sizeof (struct ipv6_opt_hdr )) -return -1 ; -if (nexthdr ==NEXTHDR_NONE ) -break ; -if (nexthdr ==NEXTHDR_FRAGMENT ) -break ; -if (skb_copy_bits (skb, start, &hdr,sizeof (hdr))) -BUG (); -if (nexthdr ==NEXTHDR_AUTH ) - hdrlen = (hdr.hdrlen+2 )<<2 ; -else - hdrlen =ipv6_optlen (&hdr); - - nexthdr = hdr.nexthdr; - len -= hdrlen; - start += hdrlen; - } - - *nexthdrp = nexthdr; -return start; -} -static int ipv6_get_l4proto (const struct sk_buff *skb,unsigned int nhoff,unsigned int *dataoff,u_int8_t *protonum) {unsigned int extoff = nhoff +sizeof (struct ipv6hdr ); -unsigned char pnum; +__be16 frag_off;int protoff; +u8 nexthdr;if (skb_copy_bits (skb, nhoff + offsetof(struct ipv6hdr , nexthdr), - &pnum,sizeof (pnum)) !=0 ) { + &nexthdr,sizeof (nexthdr)) !=0 ) {pr_debug ("ip6_conntrack_core: can't get nexthdr\n" );return -NF_ACCEPT ; } - protoff =nf_ct_ipv6_skip_exthdr (skb, extoff, &pnum, skb->len - extoff); + protoff =ipv6_skip_exthdr (skb, extoff, &nexthdr, &frag_off);/* * (protoff == skb->len) mean that the packet doesn't have no data * except of IPv6 & ext headers. but it's tracked anyway. - YK */ -if ((protoff <0 ) || (protoff > skb->len)) { +if (protoff <0 || (frag_off &ntohs (~0x7 )) !=0 ) {pr_debug ("ip6_conntrack_core: can't find proto in pkt\n" );return -NF_ACCEPT ; } *dataoff = protoff; - *protonum = pnum; + *protonum = nexthdr;return NF_ACCEPT ; }
Signature · 1 line
1.7.1
PATCH 7/19 netfilter: nf_conntrack: restrict NAT helper invocation to IPv4
In reply to [email protected]From: Patrick McHardy <[email protected]>
The NAT helpers currently only handle IPv4 packets correctly. Restrict invocation of the helpers to IPv4 in preparation of IPv6 NAT.
--- net/netfilter/nf_conntrack_amanda.c | 3 +- net/netfilter/nf_conntrack_ftp.c | 3 +- net/netfilter/nf_conntrack_h323_main.c | 41 ++++++++++++++++++++++--------- net/netfilter/nf_conntrack_irc.c | 3 +- net/netfilter/nf_conntrack_sip.c | 18 +++++++++---- net/netfilter/nf_conntrack_tftp.c | 3 +- 6 files changed, 49 insertions(+), 22 deletions(-)
net/netfilter/nf_conntrack_amanda.c +2 -1
@@ -154,7 +154,8 @@ static int amanda_help(struct sk_buff *skb, IPPROTO_TCP, NULL, &port); nf_nat_amanda =rcu_dereference (nf_nat_amanda_hook); -if (nf_nat_amanda && ct->status &IPS_NAT_MASK ) +if (nf_nat_amanda &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && + ct->status &IPS_NAT_MASK ) ret =nf_nat_amanda (skb, ctinfo, off - dataoff, len, exp);else if (nf_ct_expect_related (exp) !=0 )
net/netfilter/nf_conntrack_ftp.c +2 -1
@@ -487,7 +487,8 @@ static int help(struct sk_buff *skb,/* Now, NAT might want to mangle the packet, and register the * (possibly changed) expectation itself. */ nf_nat_ftp =rcu_dereference (nf_nat_ftp_hook); -if (nf_nat_ftp && ct->status &IPS_NAT_MASK ) +if (nf_nat_ftp &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && + ct->status &IPS_NAT_MASK ) ret =nf_nat_ftp (skb, ctinfo, search[dir][i].ftptype, matchoff, matchlen, exp);else {
net/netfilter/nf_conntrack_h323_main.c +29 -12
143 lines not on this page · raw message
net/netfilter/nf_conntrack_irc.c +2 -1
@@ -204,7 +204,8 @@ static int help(struct sk_buff *skb, unsigned int protoff, IPPROTO_TCP, NULL, &port); nf_nat_irc =rcu_dereference (nf_nat_irc_hook); -if (nf_nat_irc && ct->status &IPS_NAT_MASK ) +if (nf_nat_irc &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && + ct->status &IPS_NAT_MASK ) ret = nf_nat_irc(skb, ctinfo, addr_beg_p - ib_ptr, addr_end_p - addr_beg_p,
net/netfilter/nf_conntrack_sip.c +12 -6
@@ -981,7 +981,8 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int dataoff, IPPROTO_UDP, NULL, &rtcp_port); nf_nat_sdp_media =rcu_dereference (nf_nat_sdp_media_hook); -if (nf_nat_sdp_media && ct->status &IPS_NAT_MASK && !direct_rtp) +if (nf_nat_sdp_media &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && + ct->status &IPS_NAT_MASK && !direct_rtp) ret =nf_nat_sdp_media (skb, dataoff, dptr, datalen, rtp_exp, rtcp_exp, mediaoff, medialen, daddr);
@@ -1104,7 +1105,8 @@ static int process_sdp(struct sk_buff *skb, unsigned int dataoff,return ret;/* Update media connection address if present */ -if (maddr_len && nf_nat_sdp_addr && ct->status &IPS_NAT_MASK ) { +if (maddr_len && nf_nat_sdp_addr && +nf_ct_l3num (ct) ==NFPROTO_IPV4 && ct->status &IPS_NAT_MASK ) { ret =nf_nat_sdp_addr (skb, dataoff, dptr, datalen, mediaoff, c_hdr,SDP_HDR_MEDIA , &rtp_addr);
@@ -1116,7 +1118,8 @@ static int process_sdp(struct sk_buff *skb, unsigned int dataoff,/* Update session connection and owner addresses */ nf_nat_sdp_session =rcu_dereference (nf_nat_sdp_session_hook); -if (nf_nat_sdp_session && ct->status &IPS_NAT_MASK ) +if (nf_nat_sdp_session &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && + ct->status &IPS_NAT_MASK ) ret =nf_nat_sdp_session (skb, dataoff, dptr, datalen, sdpoff, &rtp_addr);
@@ -1275,7 +1278,8 @@ static int process_register_request(struct sk_buff *skb, unsigned int dataoff, exp->flags =NF_CT_EXPECT_PERMANENT |NF_CT_EXPECT_INACTIVE ; nf_nat_sip_expect =rcu_dereference (nf_nat_sip_expect_hook); -if (nf_nat_sip_expect && ct->status &IPS_NAT_MASK ) +if (nf_nat_sip_expect &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && + ct->status &IPS_NAT_MASK ) ret =nf_nat_sip_expect (skb, dataoff, dptr, datalen, exp, matchoff, matchlen);else {
@@ -1453,7 +1457,8 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct,else ret =process_sip_response (skb, dataoff, dptr, datalen); -if (ret ==NF_ACCEPT && ct->status &IPS_NAT_MASK ) { +if (ret ==NF_ACCEPT &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && + ct->status &IPS_NAT_MASK ) { nf_nat_sip =rcu_dereference (nf_nat_sip_hook);if (nf_nat_sip && !nf_nat_sip (skb, dataoff, dptr, datalen)) ret =NF_DROP ;
@@ -1534,7 +1539,8 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, datalen = datalen + diff - msglen; } -if (ret ==NF_ACCEPT && ct->status &IPS_NAT_MASK ) { +if (ret ==NF_ACCEPT &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && + ct->status &IPS_NAT_MASK ) { nf_nat_sip_seq_adjust =rcu_dereference (nf_nat_sip_seq_adjust_hook);if (nf_nat_sip_seq_adjust)nf_nat_sip_seq_adjust (skb, tdiff);
net/netfilter/nf_conntrack_tftp.c +2 -1
@@ -72,7 +72,8 @@ static int tftp_help(struct sk_buff *skb,nf_ct_dump_tuple (&exp->tuple); nf_nat_tftp =rcu_dereference (nf_nat_tftp_hook); -if (nf_nat_tftp && ct->status &IPS_NAT_MASK ) +if (nf_nat_tftp &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && + ct->status &IPS_NAT_MASK ) ret =nf_nat_tftp (skb, ctinfo, exp);else if (nf_ct_expect_related (exp) !=0 ) ret =NF_DROP ;
Signature · 1 line
1.7.1
PATCH 8/19 netfilter: nf_nat: add protoff argument to packet mangling functions
In reply to [email protected]From: Patrick McHardy <[email protected]>
For mangling IPv6 packets the protocol header offset needs to be known by the NAT packet mangling functions. Add a so far unused protoff argument and convert the conntrack and NAT helpers to use it in preparation of IPv6 NAT.
--- include/linux/netfilter/nf_conntrack_amanda.h | 1 + include/linux/netfilter/nf_conntrack_ftp.h | 1 + include/linux/netfilter/nf_conntrack_h323.h | 15 ++- include/linux/netfilter/nf_conntrack_irc.h | 1 + include/linux/netfilter/nf_conntrack_pptp.h | 2 + include/linux/netfilter/nf_conntrack_sip.h | 12 ++- include/net/netfilter/nf_nat_helper.h | 11 +- net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 6 +- net/ipv4/netfilter/nf_nat_amanda.c | 3 +- net/ipv4/netfilter/nf_nat_ftp.c | 3 +- net/ipv4/netfilter/nf_nat_h323.c | 48 ++++--- net/ipv4/netfilter/nf_nat_helper.c | 9 +- net/ipv4/netfilter/nf_nat_irc.c | 3 +- net/ipv4/netfilter/nf_nat_pptp.c | 6 +- net/ipv4/netfilter/nf_nat_sip.c | 96 +++++++----- net/netfilter/ipvs/ip_vs_ftp.c | 1 + net/netfilter/nf_conntrack_amanda.c | 5 +- net/netfilter/nf_conntrack_ftp.c | 3 +- net/netfilter/nf_conntrack_h323_main.c | 191 +++++++++++++++--------- net/netfilter/nf_conntrack_irc.c | 3 +- net/netfilter/nf_conntrack_pptp.c | 18 ++- net/netfilter/nf_conntrack_sip.c | 95 +++++++----- 22 files changed, 328 insertions(+), 205 deletions(-)
include/linux/netfilter/nf_conntrack_amanda.h +1 -0
@@ -4,6 +4,7 @@extern unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned int matchoff,unsigned int matchlen,struct nf_conntrack_expect *exp);
include/linux/netfilter/nf_conntrack_ftp.h +1 -0
@@ -34,6 +34,7 @@ struct nf_conntrack_expect;extern unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb,enum ip_conntrack_info ctinfo,enum nf_ct_ftp_type type, +unsigned int protoff,unsigned int matchoff,unsigned int matchlen,struct nf_conntrack_expect *exp);
include/linux/netfilter/nf_conntrack_h323.h +10 -5
@@ -36,12 +36,12 @@ extern void nf_conntrack_h245_expect(struct nf_conn *new, struct nf_conntrack_expect *this);extern void nf_conntrack_q931_expect (struct nf_conn *new,struct nf_conntrack_expect *this); -extern int (*set_h245_addr_hook) (struct sk_buff *skb, +extern int (*set_h245_addr_hook) (struct sk_buff *skb,unsigned int protoff,unsigned char **data,int dataoff,H245_TransportAddress *taddr,union nf_inet_addr *addr,__be16 port); -extern int (*set_h225_addr_hook) (struct sk_buff *skb, +extern int (*set_h225_addr_hook) (struct sk_buff *skb, unsigned int protoff, unsigned char **data, int dataoff, TransportAddress *taddr, union nf_inet_addr *addr,
@@ -49,40 +49,45 @@ extern int (*set_h225_addr_hook) (struct sk_buff *skb,extern int (*set_sig_addr_hook) (struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, -unsigned char **data, +unsigned int protoff,unsigned char **data,TransportAddress *taddr,int count);extern int (*set_ras_addr_hook) (struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, -unsigned char **data, +unsigned int protoff,unsigned char **data,TransportAddress *taddr,int count);extern int (*nat_rtp_rtcp_hook) (struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, -unsigned char **data,int dataoff, +unsigned int protoff,unsigned char **data, +int dataoff,H245_TransportAddress *taddr,__be16 port,__be16 rtp_port,struct nf_conntrack_expect *rtp_exp,struct nf_conntrack_expect *rtcp_exp);extern int (*nat_t120_hook) (struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned char **data,int dataoff,H245_TransportAddress *taddr,__be16 port,struct nf_conntrack_expect *exp);extern int (*nat_h245_hook) (struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned char **data,int dataoff,TransportAddress *taddr,__be16 port,struct nf_conntrack_expect *exp);extern int (*nat_callforwarding_hook) (struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned char **data,int dataoff,TransportAddress *taddr,__be16 port,struct nf_conntrack_expect *exp);extern int (*nat_q931_hook) (struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned char **data,TransportAddress *taddr,int idx,__be16 port,struct nf_conntrack_expect *exp);
include/linux/netfilter/nf_conntrack_irc.h +1 -0
@@ -7,6 +7,7 @@extern unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned int matchoff,unsigned int matchlen,struct nf_conntrack_expect *exp);
include/linux/netfilter/nf_conntrack_pptp.h +2 -0
@@ -303,12 +303,14 @@ struct nf_conntrack_expect;extern int (*nf_nat_pptp_hook_outbound)(struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, +unsigned int protoff,struct PptpControlHeader *ctlh,union pptp_ctrl_union *pptpReq);extern int (*nf_nat_pptp_hook_inbound)(struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, +unsigned int protoff,struct PptpControlHeader *ctlh,union pptp_ctrl_union *pptpReq);
include/linux/netfilter/nf_conntrack_sip.h +10 -2
@@ -37,10 +37,12 @@ struct sdp_media_type {struct sip_handler {const char *method;unsigned int len; -int (*request)(struct sk_buff *skb,unsigned int dataoff, +int (*request)(struct sk_buff *skb,unsigned int protoff, +unsigned int dataoff,const char **dptr,unsigned int *datalen,unsigned int cseq); -int (*response)(struct sk_buff *skb,unsigned int dataoff, +int (*response)(struct sk_buff *skb,unsigned int protoff, +unsigned int dataoff,const char **dptr,unsigned int *datalen,unsigned int cseq,unsigned int code); };
@@ -105,11 +107,13 @@ enum sdp_header_types { };extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, +unsigned int protoff,unsigned int dataoff,const char **dptr,unsigned int *datalen);extern void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb,s16 off); extern unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb, + unsigned int protoff, unsigned int dataoff, const char **dptr, unsigned int *datalen,
@@ -117,6 +121,7 @@ extern unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,unsigned int matchoff, unsigned int matchlen); extern unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, + unsigned int protoff, unsigned int dataoff, const char **dptr, unsigned int *datalen,
@@ -125,6 +130,7 @@ extern unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb,enum sdp_header_types term, const union nf_inet_addr *addr); extern unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, + unsigned int protoff, unsigned int dataoff, const char **dptr, unsigned int *datalen,
@@ -132,12 +138,14 @@ extern unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb,unsigned int matchlen, u_int16_t port);extern unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb, +unsigned int protoff,unsigned int dataoff,const char **dptr,unsigned int *datalen,unsigned int sdpoff,const union nf_inet_addr *addr); extern unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, + unsigned int protoff, unsigned int dataoff, const char **dptr, unsigned int *datalen,
include/net/netfilter/nf_nat_helper.h +8 -3
@@ -10,6 +10,7 @@ struct sk_buff; extern int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, + unsigned int protoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer,
@@ -18,12 +19,13 @@ extern int __nf_nat_mangle_tcp_packet(struct sk_buff *skb,static inline int nf_nat_mangle_tcp_packet (struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned int match_offset,unsigned int match_len,const char *rep_buffer,unsigned int rep_len) { -return __nf_nat_mangle_tcp_packet (skb, ct, ctinfo, +return __nf_nat_mangle_tcp_packet (skb, ct, ctinfo, protoff, match_offset, match_len, rep_buffer, rep_len, true); }
@@ -31,6 +33,7 @@ static inline int nf_nat_mangle_tcp_packet(struct sk_buff *skb, extern int nf_nat_mangle_udp_packet(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, + unsigned int protoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer,
@@ -41,10 +44,12 @@ extern void nf_nat_set_seq_adjust(struct nf_conn *ct, __be32 seq, s16 off);extern int nf_nat_seq_adjust (struct sk_buff *skb,struct nf_conn *ct, -enum ip_conntrack_info ctinfo); +enum ip_conntrack_info ctinfo, +unsigned int protoff);extern int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,struct nf_conn *ct, -enum ip_conntrack_info ctinfo); +enum ip_conntrack_info ctinfo, +unsigned int protoff);/* Setup NAT on this expected conntrack so it follows master, but goes * to port ct->master->saved_proto. */
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +4 -2
@@ -31,7 +31,8 @@int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,struct nf_conn *ct, -enum ip_conntrack_info ctinfo); +enum ip_conntrack_info ctinfo, +unsigned int protoff);EXPORT_SYMBOL_GPL (nf_nat_seq_adjust_hook); static bool ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
@@ -149,7 +150,8 @@ static unsigned int ipv4_confirm(unsigned int hooknum,typeof (nf_nat_seq_adjust_hook) seq_adjust; seq_adjust =rcu_dereference (nf_nat_seq_adjust_hook); -if (!seq_adjust || !seq_adjust (skb, ct, ctinfo)) { +if (!seq_adjust || + !seq_adjust (skb, ct, ctinfo,ip_hdrlen (skb))) {NF_CT_STAT_INC_ATOMIC (nf_ct_net (ct), drop);return NF_DROP ; }
net/ipv4/netfilter/nf_nat_amanda.c +2 -1
@@ -26,6 +26,7 @@ MODULE_ALIAS("ip_nat_amanda");static unsigned int help (struct sk_buff *skb,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned int matchoff,unsigned int matchlen,struct nf_conntrack_expect *exp)
@@ -61,7 +62,7 @@ static unsigned int help(struct sk_buff *skb,sprintf (buffer,"%u" , port); ret =nf_nat_mangle_udp_packet (skb, exp->master, ctinfo, - matchoff, matchlen, + protoff, matchoff, matchlen, buffer,strlen (buffer));if (ret !=NF_ACCEPT )nf_ct_unexpect_related (exp);
net/ipv4/netfilter/nf_nat_ftp.c +2 -1
@@ -55,6 +55,7 @@ static int nf_nat_ftp_fmt_cmd(enum nf_ct_ftp_type type,static unsigned int nf_nat_ftp (struct sk_buff *skb,enum ip_conntrack_info ctinfo,enum nf_ct_ftp_type type, +unsigned int protoff,unsigned int matchoff,unsigned int matchlen,struct nf_conntrack_expect *exp)
@@ -100,7 +101,7 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb,pr_debug ("calling nf_nat_mangle_tcp_packet\n" ); -if (!nf_nat_mangle_tcp_packet (skb, ct, ctinfo, matchoff, +if (!nf_nat_mangle_tcp_packet (skb, ct, ctinfo, protoff, matchoff, matchlen, buffer, buflen)) goto out;
net/ipv4/netfilter/nf_nat_h323.c +26 -22
180 lines not on this page · raw message
net/ipv4/netfilter/nf_nat_helper.c +6 -3
@@ -206,6 +206,7 @@ static void nf_nat_csum(struct sk_buff *skb, const struct iphdr *iph, void *data int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, + unsigned int protoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer,
@@ -257,6 +258,7 @@ int nf_nat_mangle_udp_packet(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, + unsigned int protoff, unsigned int match_offset, unsigned int match_len, const char *rep_buffer,
@@ -387,7 +389,8 @@ nf_nat_sack_adjust(struct sk_buff *skb,int nf_nat_seq_adjust (struct sk_buff *skb,struct nf_conn *ct, -enum ip_conntrack_info ctinfo) +enum ip_conntrack_info ctinfo, +unsigned int protoff) {struct tcphdr *tcph;int dir;
@@ -401,10 +404,10 @@ nf_nat_seq_adjust(struct sk_buff *skb, this_way = &nat->seq[dir]; other_way = &nat->seq[!dir]; -if (!skb_make_writable (skb,ip_hdrlen (skb) +sizeof (*tcph))) +if (!skb_make_writable (skb, protoff +sizeof (*tcph)))return 0 ; - tcph = (void *)skb->data +ip_hdrlen (skb); + tcph = (void *)skb->data + protoff;if (after (ntohl (tcph->seq), this_way->correction_pos)) seqoff = this_way->offset_after;else
net/ipv4/netfilter/nf_nat_irc.c +2 -1
@@ -29,6 +29,7 @@ MODULE_ALIAS("ip_nat_irc");static unsigned int help (struct sk_buff *skb,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned int matchoff,unsigned int matchlen,struct nf_conntrack_expect *exp)
@@ -66,7 +67,7 @@ static unsigned int help(struct sk_buff *skb, buffer, &ip, port); ret =nf_nat_mangle_tcp_packet (skb, exp->master, ctinfo, - matchoff, matchlen, buffer, + protoff, matchoff, matchlen, buffer,strlen (buffer));if (ret !=NF_ACCEPT )nf_ct_unexpect_related (exp);
net/ipv4/netfilter/nf_nat_pptp.c +4 -2
@@ -113,6 +113,7 @@ static int pptp_outbound_pkt(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, + unsigned int protoff, struct PptpControlHeader *ctlh, union pptp_ctrl_union *pptpReq)
@@ -175,7 +176,7 @@ pptp_outbound_pkt(struct sk_buff *skb, ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid));/* mangle packet */ - if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo, + if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff, cid_off + sizeof(struct pptp_pkt_hdr) + sizeof(struct PptpControlHeader), sizeof(new_callid), (char *)&new_callid,
@@ -216,6 +217,7 @@ static int pptp_inbound_pkt(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, + unsigned int protoff, struct PptpControlHeader *ctlh, union pptp_ctrl_union *pptpReq) {
@@ -268,7 +270,7 @@ pptp_inbound_pkt(struct sk_buff *skb,pr_debug ("altering peer call id from 0x%04x to 0x%04x\n" ,ntohs (REQ_CID (pptpReq, pcid_off)),ntohs (new_pcid)); - if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo, + if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff, pcid_off + sizeof(struct pptp_pkt_hdr) + sizeof(struct PptpControlHeader), sizeof(new_pcid), (char *)&new_pcid,
net/ipv4/netfilter/nf_nat_sip.c +54 -42
256 lines not on this page · raw message
net/netfilter/ipvs/ip_vs_ftp.c +1 -0
@@ -268,6 +268,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,* packet. */ ret =nf_nat_mangle_tcp_packet (skb, ct, ctinfo, + iph->ihl *4 , start-data, end-start, buf, buf_len);if (ret) {
net/netfilter/nf_conntrack_amanda.c +3 -2
@@ -40,6 +40,7 @@ MODULE_PARM_DESC(ts_algo, "textsearch algorithm to use (default kmp)");unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned int matchoff,unsigned int matchlen,struct nf_conntrack_expect *exp)
@@ -156,8 +157,8 @@ static int amanda_help(struct sk_buff *skb, nf_nat_amanda =rcu_dereference (nf_nat_amanda_hook);if (nf_nat_amanda &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && ct->status &IPS_NAT_MASK ) - ret =nf_nat_amanda (skb, ctinfo, off - dataoff, - len, exp); + ret =nf_nat_amanda (skb, ctinfo, protoff, + off - dataoff, len, exp);else if (nf_ct_expect_related (exp) !=0 ) ret =NF_DROP ;nf_ct_expect_put (exp);
net/netfilter/nf_conntrack_ftp.c +2 -1
@@ -48,6 +48,7 @@ module_param(loose, bool, 0600);unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb,enum ip_conntrack_info ctinfo,enum nf_ct_ftp_type type, +unsigned int protoff,unsigned int matchoff,unsigned int matchlen,struct nf_conntrack_expect *exp);
@@ -490,7 +491,7 @@ static int help(struct sk_buff *skb,if (nf_nat_ftp &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && ct->status &IPS_NAT_MASK ) ret =nf_nat_ftp (skb, ctinfo, search[dir][i].ftptype, - matchoff, matchlen, exp); + protoff, matchoff, matchlen, exp);else {/* Can't expect this? Best to drop packet now. */ if (nf_ct_expect_related (exp) !=0 )
net/netfilter/nf_conntrack_h323_main.c +119 -72
721 lines not on this page · raw message
net/netfilter/nf_conntrack_irc.c +2 -1
@@ -33,6 +33,7 @@ static DEFINE_SPINLOCK(irc_buffer_lock);unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb,enum ip_conntrack_info ctinfo, +unsigned int protoff,unsigned int matchoff,unsigned int matchlen,struct nf_conntrack_expect *exp)__read_mostly ;
@@ -206,7 +207,7 @@ static int help(struct sk_buff *skb, unsigned int protoff, nf_nat_irc =rcu_dereference (nf_nat_irc_hook);if (nf_nat_irc &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && ct->status &IPS_NAT_MASK ) - ret =nf_nat_irc (skb, ctinfo, + ret =nf_nat_irc (skb, ctinfo, protoff, addr_beg_p - ib_ptr, addr_end_p - addr_beg_p, exp);
net/netfilter/nf_conntrack_pptp.c +10 -8
@@ -45,14 +45,14 @@ static DEFINE_SPINLOCK(nf_pptp_lock);int (*nf_nat_pptp_hook_outbound)(struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, -struct PptpControlHeader *ctlh, +unsigned int protoff,struct PptpControlHeader *ctlh,union pptp_ctrl_union *pptpReq)__read_mostly ;EXPORT_SYMBOL_GPL (nf_nat_pptp_hook_outbound);int (*nf_nat_pptp_hook_inbound)(struct sk_buff *skb,struct nf_conn *ct,enum ip_conntrack_info ctinfo, -struct PptpControlHeader *ctlh, +unsigned int protoff,struct PptpControlHeader *ctlh,union pptp_ctrl_union *pptpReq)__read_mostly ;EXPORT_SYMBOL_GPL (nf_nat_pptp_hook_inbound);
@@ -262,7 +262,7 @@ out_unexpect_orig: } static inline int -pptp_inbound_pkt(struct sk_buff *skb, +pptp_inbound_pkt(struct sk_buff *skb, unsigned int protoff, struct PptpControlHeader *ctlh, union pptp_ctrl_union *pptpReq, unsigned int reqlen,
@@ -376,7 +376,8 @@ pptp_inbound_pkt(struct sk_buff *skb, nf_nat_pptp_inbound =rcu_dereference (nf_nat_pptp_hook_inbound);if (nf_nat_pptp_inbound && ct->status &IPS_NAT_MASK ) -return nf_nat_pptp_inbound (skb, ct, ctinfo, ctlh, pptpReq); +return nf_nat_pptp_inbound (skb, ct, ctinfo, + protoff, ctlh, pptpReq);return NF_ACCEPT ; invalid:
@@ -389,7 +390,7 @@ invalid: } static inline int -pptp_outbound_pkt(struct sk_buff *skb, +pptp_outbound_pkt(struct sk_buff *skb, unsigned int protoff, struct PptpControlHeader *ctlh, union pptp_ctrl_union *pptpReq, unsigned int reqlen,
@@ -471,7 +472,8 @@ pptp_outbound_pkt(struct sk_buff *skb, nf_nat_pptp_outbound =rcu_dereference (nf_nat_pptp_hook_outbound);if (nf_nat_pptp_outbound && ct->status &IPS_NAT_MASK ) -return nf_nat_pptp_outbound (skb, ct, ctinfo, ctlh, pptpReq); +return nf_nat_pptp_outbound (skb, ct, ctinfo, + protoff, ctlh, pptpReq);return NF_ACCEPT ; invalid:
@@ -570,11 +572,11 @@ conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff,* established from PNS->PAC. However, RFC makes no guarantee */ if (dir ==IP_CT_DIR_ORIGINAL )/* client -> server (PNS -> PAC) */ - ret =pptp_outbound_pkt (skb, ctlh, pptpReq, reqlen, ct, + ret =pptp_outbound_pkt (skb, protoff, ctlh, pptpReq, reqlen, ct, ctinfo);else /* server -> client (PAC -> PNS) */ - ret =pptp_inbound_pkt (skb, ctlh, pptpReq, reqlen, ct, + ret =pptp_inbound_pkt (skb, protoff, ctlh, pptpReq, reqlen, ct, ctinfo);pr_debug ("sstate: %d->%d, cstate: %d->%d\n" , oldsstate, info->sstate, oldcstate, info->cstate);
net/netfilter/nf_conntrack_sip.c +58 -37
288 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH 9/19 netfilter: add protocol independant NAT core
In reply to [email protected]From: Patrick McHardy <[email protected]>
Convert the IPv4 NAT implementation to a protocol independant core and address family specific modules.
---
include/linux/netfilter.h | 14 +-
include/linux/netfilter/nf_nat.h | 8 +
include/linux/netfilter/nfnetlink_conntrack.h | 6 +-
include/linux/netfilter_ipv4.h | 1 -
include/net/netfilter/nf_conntrack_expect.h | 2 +-
include/net/netfilter/nf_nat.h | 2 +-
include/net/netfilter/nf_nat_core.h | 5 +-
include/net/netfilter/nf_nat_l3proto.h | 47 ++
include/net/netfilter/nf_nat_l4proto.h | 71 +++
include/net/netfilter/nf_nat_protocol.h | 67 ---
include/net/netfilter/nf_nat_rule.h | 15 -
include/net/netns/conntrack.h | 4 +
include/net/netns/ipv4.h | 2 -
net/ipv4/netfilter.c | 37 --
net/ipv4/netfilter/Kconfig | 65 +--
net/ipv4/netfilter/Makefile | 11 +-
net/ipv4/netfilter/ipt_MASQUERADE.c | 15 +-
net/ipv4/netfilter/ipt_NETMAP.c | 15 +-
net/ipv4/netfilter/ipt_REDIRECT.c | 15 +-
.../{nf_nat_standalone.c => iptable_nat.c} | 264 +++++-----
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 6 -
net/ipv4/netfilter/nf_nat_amanda.c | 1 -
net/ipv4/netfilter/nf_nat_ftp.c | 1 -
net/ipv4/netfilter/nf_nat_h323.c | 23 +-
net/ipv4/netfilter/nf_nat_irc.c | 1 -
net/ipv4/netfilter/nf_nat_l3proto_ipv4.c | 281 +++++++++
net/ipv4/netfilter/nf_nat_pptp.c | 15 +-
net/ipv4/netfilter/nf_nat_proto_gre.c | 30 +-
net/ipv4/netfilter/nf_nat_proto_icmp.c | 24 +-
net/ipv4/netfilter/nf_nat_rule.c | 214 -------
net/ipv4/netfilter/nf_nat_sip.c | 19 +-
net/ipv4/netfilter/nf_nat_tftp.c | 1 -
net/netfilter/Kconfig | 24 +
net/netfilter/Makefile | 11 +
net/netfilter/core.c | 5 +
net/netfilter/nf_conntrack_core.c | 6 +
net/netfilter/nf_conntrack_netlink.c | 35 +-
net/netfilter/nf_conntrack_proto_tcp.c | 8 +-
net/netfilter/nf_conntrack_sip.c | 6 +-
net/{ipv4 => }/netfilter/nf_nat_core.c | 599 ++++++++++----------
net/{ipv4 => }/netfilter/nf_nat_helper.c | 100 ++--
net/{ipv4 => }/netfilter/nf_nat_proto_common.c | 54 +-
net/{ipv4 => }/netfilter/nf_nat_proto_dccp.c | 56 ++-
net/{ipv4 => }/netfilter/nf_nat_proto_sctp.c | 53 +-
net/{ipv4 => }/netfilter/nf_nat_proto_tcp.c | 40 +-
net/{ipv4 => }/netfilter/nf_nat_proto_udp.c | 42 +-
net/{ipv4 => }/netfilter/nf_nat_proto_udplite.c | 58 ++-
net/{ipv4 => }/netfilter/nf_nat_proto_unknown.c | 16 +-
net/netfilter/xt_nat.c | 167 ++++++
49 files changed, 1427 insertions(+), 1135 deletions(-)
create mode 100644 include/net/netfilter/nf_nat_l3proto.h
create mode 100644 include/net/netfilter/nf_nat_l4proto.h
delete mode 100644 include/net/netfilter/nf_nat_protocol.h
delete mode 100644 include/net/netfilter/nf_nat_rule.h
rename net/ipv4/netfilter/{nf_nat_standalone.c => iptable_nat.c} (52%)
create mode 100644 net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
delete mode 100644 net/ipv4/netfilter/nf_nat_rule.c
rename net/{ipv4 => }/netfilter/nf_nat_core.c (56%)
rename net/{ipv4 => }/netfilter/nf_nat_helper.c (83%)
rename net/{ipv4 => }/netfilter/nf_nat_proto_common.c (62%)
rename net/{ipv4 => }/netfilter/nf_nat_proto_dccp.c (61%)
rename net/{ipv4 => }/netfilter/nf_nat_proto_sctp.c (61%)
rename net/{ipv4 => }/netfilter/nf_nat_proto_tcp.c (65%)
rename net/{ipv4 => }/netfilter/nf_nat_proto_udp.c (60%)
rename net/{ipv4 => }/netfilter/nf_nat_proto_udplite.c (58%)
rename net/{ipv4 => }/netfilter/nf_nat_proto_unknown.c (76%)
create mode 100644 net/netfilter/xt_nat.cinclude/linux/netfilter.h +6 -8
@@ -342,7 +342,7 @@ extern int nf_register_afinfo(const struct nf_afinfo *afinfo);extern void nf_unregister_afinfo (const struct nf_afinfo *afinfo);#include <net/flow.h> -extern void (*ip_nat_decode_session)(struct sk_buff *,struct flowi *); +extern void (*nf_nat_decode_session_hook)(struct sk_buff *,struct flowi *);static inline void nf_nat_decode_session (struct sk_buff *skb,struct flowi *fl,u_int8_t family)
@@ -350,13 +350,11 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)#ifdef CONFIG_NF_NAT_NEEDED void (*decodefn)(struct sk_buff *,struct flowi *); -if (family ==AF_INET ) { -rcu_read_lock (); - decodefn =rcu_dereference (ip_nat_decode_session); -if (decodefn) -decodefn (skb, fl); -rcu_read_unlock (); - } +rcu_read_lock (); + decodefn =rcu_dereference (nf_nat_decode_session_hook); +if (decodefn) +decodefn (skb, fl); +rcu_read_unlock ();#endif }
include/linux/netfilter/nf_nat.h +8 -0
@@ -22,4 +22,12 @@ struct nf_nat_ipv4_multi_range_compat { struct nf_nat_ipv4_range range[1]; }; +struct nf_nat_range { +unsigned int flags; +union nf_inet_addr min_addr; +union nf_inet_addr max_addr; +union nf_conntrack_man_proto min_proto; +union nf_conntrack_man_proto max_proto; +}; +#endif /* _NETFILTER_NF_NAT_H */
include/linux/netfilter/nfnetlink_conntrack.h +4 -2
@@ -142,8 +142,10 @@ enum ctattr_tstamp {enum ctattr_nat {CTA_NAT_UNSPEC , -CTA_NAT_MINIP , -CTA_NAT_MAXIP , +CTA_NAT_V4_MINIP , +#define CTA_NAT_MINIP CTA_NAT_V4_MINIP + CTA_NAT_V4_MAXIP, +#define CTA_NAT_MAXIP CTA_NAT_V4_MAXIP CTA_NAT_PROTO, __CTA_NAT_MAX };
include/linux/netfilter_ipv4.h +0 -1
@@ -79,7 +79,6 @@ enum nf_ip_hook_priorities {#ifdef __KERNEL__extern int ip_route_me_harder (struct sk_buff *skb,unsigned addr_type); -extern int ip_xfrm_me_harder (struct sk_buff *skb);extern __sum16 nf_ip_checksum (struct sk_buff *skb,unsigned int hook,unsigned int dataoff,u_int8_t protocol);#endif /*__KERNEL__*/
include/net/netfilter/nf_conntrack_expect.h +1 -1
@@ -43,7 +43,7 @@ struct nf_conntrack_expect {unsigned int class;#ifdef CONFIG_NF_NAT_NEEDED -__be32 saved_ip; +union nf_inet_addr saved_addr;/* This is the original per-proto part, used to map the * expected connection the way the recipient expects. */ union nf_conntrack_man_proto saved_proto;
include/net/netfilter/nf_nat.h +1 -1
@@ -50,7 +50,7 @@ struct nf_conn_nat {/* Set up the info structure to map into this range. */ extern unsigned int nf_nat_setup_info (struct nf_conn *ct, -const struct nf_nat_ipv4_range *range, +const struct nf_nat_range *range,enum nf_nat_manip_type maniptype);/* Is this tuple already taken? (not by us)*/
include/net/netfilter/nf_nat_core.h +1 -4
@@ -12,10 +12,7 @@ extern unsigned int nf_nat_packet(struct nf_conn *ct,unsigned int hooknum, struct sk_buff *skb); -extern int nf_nat_icmp_reply_translation (struct nf_conn *ct, -enum ip_conntrack_info ctinfo, -unsigned int hooknum, -struct sk_buff *skb); +extern int nf_xfrm_me_harder (struct sk_buff *skb,unsigned int family);static inline int nf_nat_initialized (struct nf_conn *ct,enum nf_nat_manip_type manip)
include/net/netfilter/nf_nat_l3proto.h new file +47 -0
47 lines not on this page · raw message
include/net/netfilter/nf_nat_l4proto.h new file +71 -0
71 lines not on this page · raw message
include/net/netfilter/nf_nat_protocol.h deleted +0 -67
67 lines not on this page · raw message
include/net/netfilter/nf_nat_rule.h deleted +0 -15
@@ -1,15 +0,0 @@ -#ifndef _NF_NAT_RULE_H -#define _NF_NAT_RULE_H -#include <net/netfilter/nf_conntrack.h> -#include <net/netfilter/nf_nat.h> -#include <linux/netfilter_ipv4/ip_tables.h> - -extern int nf_nat_rule_init (void )__init ; -extern void nf_nat_rule_cleanup (void ); -extern int nf_nat_rule_find (struct sk_buff *skb, -unsigned int hooknum, -const struct net_device *in, -const struct net_device *out, -struct nf_conn *ct); - -#endif /* _NF_NAT_RULE_H */
include/net/netns/conntrack.h +4 -0
@@ -83,6 +83,10 @@ struct netns_ct {int sysctl_auto_assign_helper;bool auto_assign_helper_warned;struct nf_ip_net nf_ct_proto; +#ifdef CONFIG_NF_NAT_NEEDED +struct hlist_head *nat_bysource; +unsigned int nat_htable_size; +#endif #ifdef CONFIG_SYSCTL struct ctl_table_header *sysctl_header;struct ctl_table_header *acct_sysctl_header;
include/net/netns/ipv4.h +0 -2
@@ -51,8 +51,6 @@ struct netns_ipv4 {struct xt_table *iptable_security;#endif struct xt_table *nat_table; -struct hlist_head *nat_bysource; -unsigned int nat_htable_size;#endif int sysctl_icmp_echo_ignore_all;
net/ipv4/netfilter.c +0 -37
@@ -72,43 +72,6 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned int addr_type) }EXPORT_SYMBOL (ip_route_me_harder); -#ifdef CONFIG_XFRM -int ip_xfrm_me_harder (struct sk_buff *skb) -{ -struct flowi fl; -unsigned int hh_len; -struct dst_entry *dst; - -if (IPCB (skb)->flags &IPSKB_XFRM_TRANSFORMED ) -return 0 ; -if (xfrm_decode_session (skb, &fl,AF_INET ) <0 ) -return -1 ; - - dst =skb_dst (skb); -if (dst->xfrm) - dst = ((struct xfrm_dst *)dst)->route; -dst_hold (dst); - - dst =xfrm_lookup (dev_net (dst->dev), dst, &fl, skb->sk,0 ); -if (IS_ERR (dst)) -return -1 ; - -skb_dst_drop (skb); -skb_dst_set (skb, dst); - -/* Change in oif may mean change in hh_len. */ - hh_len =skb_dst (skb)->dev->hard_header_len; -if (skb_headroom (skb) < hh_len && -pskb_expand_head (skb, hh_len -skb_headroom (skb),0 ,GFP_ATOMIC )) -return -1 ; -return 0 ; -} -EXPORT_SYMBOL (ip_xfrm_me_harder); -#endif - -void (*ip_nat_decode_session)(struct sk_buff *,struct flowi *); -EXPORT_SYMBOL (ip_nat_decode_session); -/* * Extra routing may needed on local out, as the QUEUE target never * returns control to the table.
net/ipv4/netfilter/Kconfig +23 -42
130 lines not on this page · raw message
net/ipv4/netfilter/Makefile +3 -8
@@ -10,13 +10,11 @@ nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o endif endif -nf_nat-y := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o -iptable_nat-y := nf_nat_rule.o nf_nat_standalone.o - # connection tracking obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o -obj-$(CONFIG_NF_NAT) += nf_nat.o +nf_nat_ipv4-y := nf_nat_l3proto_ipv4.o nf_nat_proto_icmp.o +obj-$(CONFIG_NF_NAT_IPV4) += nf_nat_ipv4.o # defrag obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
@@ -32,10 +30,7 @@ obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o # NAT protocols (nf_nat) -obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o -obj-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o -obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o # generic IP tables obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
@@ -43,7 +38,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o # the three instances of ip_tables obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o -obj-$(CONFIG_NF_NAT) += iptable_nat.o +obj-$(CONFIG_NF_NAT_IPV4) += iptable_nat.o obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
net/ipv4/netfilter/ipt_MASQUERADE.c +9 -6
@@ -19,9 +19,9 @@#include <net/ip.h> #include <net/checksum.h> #include <net/route.h> -#include <net/netfilter/nf_nat_rule.h> #include <linux/netfilter_ipv4.h> #include <linux/netfilter/x_tables.h> +#include <net/netfilter/nf_nat.h> MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Netfilter Core Team <[email protected]>" );
@@ -49,7 +49,7 @@ masquerade_tg(struct sk_buff *skb, const struct xt_action_param *par)struct nf_conn *ct;struct nf_conn_nat *nat;enum ip_conntrack_info ctinfo; -struct nf_nat_ipv4_range newrange; +struct nf_nat_range newrange;const struct nf_nat_ipv4_multi_range_compat *mr;const struct rtable *rt;__be32 newsrc, nh;
@@ -80,10 +80,13 @@ masquerade_tg(struct sk_buff *skb, const struct xt_action_param *par) nat->masq_index = par->out->ifindex;/* Transfer from original range. */ - newrange = ((struct nf_nat_ipv4_range ) - { mr->range[0 ].flags |NF_NAT_RANGE_MAP_IPS , - newsrc, newsrc, - mr->range[0 ].min, mr->range[0 ].max }); +memset (&newrange.min_addr,0 ,sizeof (newrange.min_addr)); +memset (&newrange.max_addr,0 ,sizeof (newrange.max_addr)); + newrange.flags = mr->range[0 ].flags |NF_NAT_RANGE_MAP_IPS ; + newrange.min_addr.ip = newsrc; + newrange.max_addr.ip = newsrc; + newrange.min_proto = mr->range[0 ].min; + newrange.max_proto = mr->range[0 ].max;/* Hand modified range to generic setup. */ return nf_nat_setup_info (ct, &newrange,NF_NAT_MANIP_SRC );
net/ipv4/netfilter/ipt_NETMAP.c +9 -6
@@ -16,7 +16,7 @@#include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> #include <linux/netfilter/x_tables.h> -#include <net/netfilter/nf_nat_rule.h> +#include <net/netfilter/nf_nat.h> MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Svenning Soerensen <[email protected]>" );
@@ -44,7 +44,7 @@ netmap_tg(struct sk_buff *skb, const struct xt_action_param *par)enum ip_conntrack_info ctinfo;__be32 new_ip, netmask;const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; -struct nf_nat_ipv4_range newrange; +struct nf_nat_range newrange; NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING || par->hooknum == NF_INET_POST_ROUTING ||
@@ -61,10 +61,13 @@ netmap_tg(struct sk_buff *skb, const struct xt_action_param *par) new_ip =ip_hdr (skb)->saddr & ~netmask; new_ip |= mr->range[0 ].min_ip & netmask; - newrange = ((struct nf_nat_ipv4_range ) - { mr->range[0 ].flags |NF_NAT_RANGE_MAP_IPS , - new_ip, new_ip, - mr->range[0 ].min, mr->range[0 ].max }); +memset (&newrange.min_addr,0 ,sizeof (newrange.min_addr)); +memset (&newrange.max_addr,0 ,sizeof (newrange.max_addr)); + newrange.flags = mr->range[0 ].flags |NF_NAT_RANGE_MAP_IPS ; + newrange.min_addr.ip = new_ip; + newrange.max_addr.ip = new_ip; + newrange.min_proto = mr->range[0 ].min; + newrange.max_proto = mr->range[0 ].max;/* Hand modified range to generic setup. */ return nf_nat_setup_info (ct, &newrange,HOOK2MANIP (par->hooknum));
net/ipv4/netfilter/ipt_REDIRECT.c +9 -6
@@ -19,7 +19,7 @@#include <net/checksum.h> #include <linux/netfilter_ipv4.h> #include <linux/netfilter/x_tables.h> -#include <net/netfilter/nf_nat_rule.h> +#include <net/netfilter/nf_nat.h> MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Netfilter Core Team <[email protected]>" );
@@ -48,7 +48,7 @@ redirect_tg(struct sk_buff *skb, const struct xt_action_param *par)enum ip_conntrack_info ctinfo;__be32 newdst;const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo; -struct nf_nat_ipv4_range newrange; +struct nf_nat_range newrange;NF_CT_ASSERT (par->hooknum ==NF_INET_PRE_ROUTING || par->hooknum ==NF_INET_LOCAL_OUT );
@@ -76,10 +76,13 @@ redirect_tg(struct sk_buff *skb, const struct xt_action_param *par) }/* Transfer from original range. */ - newrange = ((struct nf_nat_ipv4_range ) - { mr->range[0 ].flags |NF_NAT_RANGE_MAP_IPS , - newdst, newdst, - mr->range[0 ].min, mr->range[0 ].max }); +memset (&newrange.min_addr,0 ,sizeof (newrange.min_addr)); +memset (&newrange.max_addr,0 ,sizeof (newrange.max_addr)); + newrange.flags = mr->range[0 ].flags |NF_NAT_RANGE_MAP_IPS ; + newrange.min_addr.ip = newdst; + newrange.max_addr.ip = newdst; + newrange.min_proto = mr->range[0 ].min; + newrange.max_proto = mr->range[0 ].max;/* Hand modified range to generic setup. */ return nf_nat_setup_info (ct, &newrange,NF_NAT_MANIP_DST );
net/ipv4/netfilter/iptable_nat.c renamed from net/ipv4/netfilter/nf_nat_standalone.c +129 -135
400 lines not on this page · raw message
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +0 -6
@@ -29,12 +29,6 @@#include <net/netfilter/ipv4/nf_defrag_ipv4.h> #include <net/netfilter/nf_log.h> -int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, -struct nf_conn *ct, -enum ip_conntrack_info ctinfo, -unsigned int protoff); -EXPORT_SYMBOL_GPL (nf_nat_seq_adjust_hook); -static bool ipv4_pkt_to_tuple (const struct sk_buff *skb,unsigned int nhoff,struct nf_conntrack_tuple *tuple) {
net/ipv4/netfilter/nf_nat_amanda.c +0 -1
@@ -16,7 +16,6 @@#include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_nat_helper.h> -#include <net/netfilter/nf_nat_rule.h> #include <linux/netfilter/nf_conntrack_amanda.h> MODULE_AUTHOR ("Brian J. Murrell <[email protected]>" );
net/ipv4/netfilter/nf_nat_ftp.c +0 -1
@@ -15,7 +15,6 @@#include <linux/netfilter_ipv4.h> #include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat_helper.h> -#include <net/netfilter/nf_nat_rule.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_expect.h> #include <linux/netfilter/nf_conntrack_ftp.h>
net/ipv4/netfilter/nf_nat_h323.c +12 -11
@@ -15,7 +15,6 @@#include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat_helper.h> -#include <net/netfilter/nf_nat_rule.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_expect.h> #include <linux/netfilter/nf_conntrack_h323.h>
@@ -392,7 +391,7 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct,static void ip_nat_q931_expect (struct nf_conn *new,struct nf_conntrack_expect *this) { -struct nf_nat_ipv4_range range; +struct nf_nat_range range;if (this->tuple.src.u3.ip !=0 ) {/* Only accept calls from GK */ nf_nat_follow_master (new, this);
@@ -404,14 +403,15 @@ static void ip_nat_q931_expect(struct nf_conn *new,/* Change src to where master sends to */ range.flags =NF_NAT_RANGE_MAP_IPS ; - range.min_ip = range.max_ip = new->tuplehash[!this->dir].tuple.src.u3.ip; + range.min_addr = range.max_addr = + new->tuplehash[!this->dir].tuple.src.u3;nf_nat_setup_info (new, &range,NF_NAT_MANIP_SRC );/* For DST manip, map port here to where it's expected. */ range.flags = (NF_NAT_RANGE_MAP_IPS |NF_NAT_RANGE_PROTO_SPECIFIED ); - range.min = range.max = this->saved_proto; - range.min_ip = range.max_ip = - new->master->tuplehash[!this->dir].tuple.src.u3.ip; + range.min_proto = range.max_proto = this->saved_proto; + range.min_addr = range.max_addr = + new->master->tuplehash[!this->dir].tuple.src.u3;nf_nat_setup_info (new, &range,NF_NAT_MANIP_DST ); }
@@ -490,20 +490,21 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,static void ip_nat_callforwarding_expect (struct nf_conn *new,struct nf_conntrack_expect *this) { -struct nf_nat_ipv4_range range; +struct nf_nat_range range;/* This must be a fresh one. */ BUG_ON (new->status &IPS_NAT_DONE_MASK );/* Change src to where master sends to */ range.flags =NF_NAT_RANGE_MAP_IPS ; - range.min_ip = range.max_ip = new->tuplehash[!this->dir].tuple.src.u3.ip; + range.min_addr = range.max_addr = + new->tuplehash[!this->dir].tuple.src.u3;nf_nat_setup_info (new, &range,NF_NAT_MANIP_SRC );/* For DST manip, map port here to where it's expected. */ range.flags = (NF_NAT_RANGE_MAP_IPS |NF_NAT_RANGE_PROTO_SPECIFIED ); - range.min = range.max = this->saved_proto; - range.min_ip = range.max_ip = this->saved_ip; + range.min_proto = range.max_proto = this->saved_proto; + range.min_addr = range.max_addr = this->saved_addr;nf_nat_setup_info (new, &range,NF_NAT_MANIP_DST ); }
@@ -519,7 +520,7 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,u_int16_t nated_port;/* Set expectations for NAT */ - exp->saved_ip = exp->tuple.dst.u3.ip; + exp->saved_addr = exp->tuple.dst.u3; exp->tuple.dst.u3.ip = ct->tuplehash[!dir].tuple.dst.u3.ip; exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; exp->expectfn = ip_nat_callforwarding_expect;
net/ipv4/netfilter/nf_nat_irc.c +0 -1
@@ -17,7 +17,6 @@#include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat_helper.h> -#include <net/netfilter/nf_nat_rule.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_expect.h> #include <linux/netfilter/nf_conntrack_irc.h>
net/ipv4/netfilter/nf_nat_l3proto_ipv4.c new file +281 -0
281 lines not on this page · raw message
net/ipv4/netfilter/nf_nat_pptp.c +7 -8
@@ -22,7 +22,6 @@#include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat_helper.h> -#include <net/netfilter/nf_nat_rule.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_conntrack_zones.h>
@@ -47,7 +46,7 @@ static void pptp_nat_expected(struct nf_conn *ct,struct nf_conntrack_tuple t;const struct nf_ct_pptp_master *ct_pptp_info;const struct nf_nat_pptp *nat_pptp_info; -struct nf_nat_ipv4_range range; +struct nf_nat_range range; ct_pptp_info =nfct_help_data (master); nat_pptp_info = &nfct_nat (master)->help.nat_pptp_info;
@@ -89,21 +88,21 @@ static void pptp_nat_expected(struct nf_conn *ct,/* Change src to where master sends to */ range.flags =NF_NAT_RANGE_MAP_IPS ; - range.min_ip = range.max_ip - = ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip; + range.min_addr = range.max_addr + = ct->master->tuplehash[!exp->dir].tuple.dst.u3;if (exp->dir ==IP_CT_DIR_ORIGINAL ) { range.flags |=NF_NAT_RANGE_PROTO_SPECIFIED ; - range.min = range.max = exp->saved_proto; + range.min_proto = range.max_proto = exp->saved_proto; }nf_nat_setup_info (ct, &range,NF_NAT_MANIP_SRC );/* For DST manip, map port here to where it's expected. */ range.flags =NF_NAT_RANGE_MAP_IPS ; - range.min_ip = range.max_ip - = ct->master->tuplehash[!exp->dir].tuple.src.u3.ip; + range.min_addr = range.max_addr + = ct->master->tuplehash[!exp->dir].tuple.src.u3;if (exp->dir ==IP_CT_DIR_REPLY ) { range.flags |=NF_NAT_RANGE_PROTO_SPECIFIED ; - range.min = range.max = exp->saved_proto; + range.min_proto = range.max_proto = exp->saved_proto; }nf_nat_setup_info (ct, &range,NF_NAT_MANIP_DST ); }
net/ipv4/netfilter/nf_nat_proto_gre.c +15 -15
@@ -28,8 +28,7 @@#include <linux/ip.h> #include <net/netfilter/nf_nat.h> -#include <net/netfilter/nf_nat_rule.h> -#include <net/netfilter/nf_nat_protocol.h> +#include <net/netfilter/nf_nat_l4proto.h> #include <linux/netfilter/nf_conntrack_proto_gre.h> MODULE_LICENSE ("GPL" );
@@ -38,8 +37,9 @@ MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");/* generate unique tuple ... */ static void -gre_unique_tuple (struct nf_conntrack_tuple *tuple, -const struct nf_nat_ipv4_range *range, +gre_unique_tuple (const struct nf_nat_l3proto *l3proto, +struct nf_conntrack_tuple *tuple, +const struct nf_nat_range *range,enum nf_nat_manip_type maniptype,const struct nf_conn *ct) {
@@ -62,8 +62,8 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple, min =1 ; range_size =0xffff ; }else { - min =ntohs (range->min.gre.key); - range_size =ntohs (range->max.gre.key) - min +1 ; + min =ntohs (range->min_proto.gre.key); + range_size =ntohs (range->max_proto.gre.key) - min +1 ; }pr_debug ("min = %u, range_size = %u\n" , min, range_size);
@@ -80,14 +80,14 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,/* manipulate a GRE packet according to maniptype */ static bool -gre_manip_pkt (struct sk_buff *skb,unsigned int iphdroff, +gre_manip_pkt (struct sk_buff *skb, +const struct nf_nat_l3proto *l3proto, +unsigned int iphdroff,unsigned int hdroff,const struct nf_conntrack_tuple *tuple,enum nf_nat_manip_type maniptype) {const struct gre_hdr *greh;struct gre_hdr_pptp *pgreh; -const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff); -unsigned int hdroff = iphdroff + iph->ihl *4 ;/* pgreh includes two optional 32bit fields which are not required * to be there. That's where the magic '8' comes from */
@@ -117,24 +117,24 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,return true; } -static const struct nf_nat_protocol gre = { - .protonum =IPPROTO_GRE , +static const struct nf_nat_l4proto gre = { + .l4proto =IPPROTO_GRE , .manip_pkt = gre_manip_pkt, - .in_range = nf_nat_proto_in_range, + .in_range = nf_nat_l4proto_in_range, .unique_tuple = gre_unique_tuple, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .nlattr_to_range = nf_nat_proto_nlattr_to_range, + .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, #endif };static int __init nf_nat_proto_gre_init (void ) { -return nf_nat_protocol_register (&gre); +return nf_nat_l4proto_register (NFPROTO_IPV4 , &gre); } static void __exit nf_nat_proto_gre_fini(void) { -nf_nat_protocol_unregister (&gre); +nf_nat_l4proto_unregister (NFPROTO_IPV4 , &gre); }module_init (nf_nat_proto_gre_init);
net/ipv4/netfilter/nf_nat_proto_icmp.c +12 -12
@@ -15,8 +15,7 @@#include <linux/netfilter.h> #include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat_core.h> -#include <net/netfilter/nf_nat_rule.h> -#include <net/netfilter/nf_nat_protocol.h> +#include <net/netfilter/nf_nat_l4proto.h> static bool icmp_in_range(const struct nf_conntrack_tuple *tuple,
@@ -29,8 +28,9 @@ icmp_in_range(const struct nf_conntrack_tuple *tuple, }static void -icmp_unique_tuple (struct nf_conntrack_tuple *tuple, -const struct nf_nat_ipv4_range *range, +icmp_unique_tuple (const struct nf_nat_l3proto *l3proto, +struct nf_conntrack_tuple *tuple, +const struct nf_nat_range *range,enum nf_nat_manip_type maniptype,const struct nf_conn *ct) {
@@ -38,13 +38,14 @@ icmp_unique_tuple(struct nf_conntrack_tuple *tuple,unsigned int range_size;unsigned int i; - range_size =ntohs (range->max.icmp.id) -ntohs (range->min.icmp.id) +1 ; + range_size =ntohs (range->max_proto.icmp.id) - +ntohs (range->min_proto.icmp.id) +1 ;/* If no range specified... */ if (!(range->flags &NF_NAT_RANGE_PROTO_SPECIFIED )) range_size =0xFFFF ;for (i =0 ; ; ++id) { - tuple->src.u.icmp.id =htons (ntohs (range->min.icmp.id) + + tuple->src.u.icmp.id =htons (ntohs (range->min_proto.icmp.id) + (id % range_size));if (++i == range_size || !nf_nat_used_tuple (tuple, ct))return ;
@@ -54,13 +55,12 @@ icmp_unique_tuple(struct nf_conntrack_tuple *tuple,static bool icmp_manip_pkt (struct sk_buff *skb, -unsigned int iphdroff, +const struct nf_nat_l3proto *l3proto, +unsigned int iphdroff,unsigned int hdroff,const struct nf_conntrack_tuple *tuple,enum nf_nat_manip_type maniptype) { -const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);struct icmphdr *hdr; -unsigned int hdroff = iphdroff + iph->ihl*4 ;if (!skb_make_writable (skb, hdroff +sizeof (*hdr)))return false;
@@ -72,12 +72,12 @@ icmp_manip_pkt(struct sk_buff *skb,return true; } -const struct nf_nat_protocol nf_nat_protocol_icmp = { - .protonum =IPPROTO_ICMP , +const struct nf_nat_l4proto nf_nat_l4proto_icmp = { + .l4proto =IPPROTO_ICMP , .manip_pkt = icmp_manip_pkt, .in_range = icmp_in_range, .unique_tuple = icmp_unique_tuple, #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) - .nlattr_to_range = nf_nat_proto_nlattr_to_range, + .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, #endif };
net/ipv4/netfilter/nf_nat_rule.c deleted +0 -214
214 lines not on this page · raw message
net/ipv4/netfilter/nf_nat_sip.c +9 -10
@@ -19,7 +19,6 @@#include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat_helper.h> -#include <net/netfilter/nf_nat_rule.h> #include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_expect.h> #include <linux/netfilter/nf_conntrack_sip.h>
@@ -255,15 +254,15 @@ static void ip_nat_sip_seq_adjust(struct sk_buff *skb, s16 off)static void ip_nat_sip_expected (struct nf_conn *ct,struct nf_conntrack_expect *exp) { -struct nf_nat_ipv4_range range; +struct nf_nat_range range;/* This must be a fresh one. */ BUG_ON (ct->status &IPS_NAT_DONE_MASK );/* For DST manip, map port here to where it's expected. */ range.flags = (NF_NAT_RANGE_MAP_IPS |NF_NAT_RANGE_PROTO_SPECIFIED ); - range.min = range.max = exp->saved_proto; - range.min_ip = range.max_ip = exp->saved_ip; + range.min_proto = range.max_proto = exp->saved_proto; + range.min_addr = range.max_addr = exp->saved_addr;nf_nat_setup_info (ct, &range,NF_NAT_MANIP_DST );/* Change src to where master sends to, but only if the connection
@@ -271,8 +270,8 @@ static void ip_nat_sip_expected(struct nf_conn *ct,if (ct->tuplehash[IP_CT_DIR_ORIGINAL ].tuple.src.u3.ip == ct->master->tuplehash[exp->dir].tuple.src.u3.ip) { range.flags =NF_NAT_RANGE_MAP_IPS ; - range.min_ip = range.max_ip - = ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip; + range.min_addr = range.max_addr + = ct->master->tuplehash[!exp->dir].tuple.dst.u3;nf_nat_setup_info (ct, &range,NF_NAT_MANIP_SRC ); } }
@@ -307,7 +306,7 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int protoff,else port =ntohs (exp->tuple.dst.u.udp.port); - exp->saved_ip = exp->tuple.dst.u3.ip; + exp->saved_addr = exp->tuple.dst.u3; exp->tuple.dst.u3.ip = newip; exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port; exp->dir = !dir;
@@ -329,7 +328,7 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int protoff,if (port ==0 )return NF_DROP ; - if (exp->tuple.dst.u3.ip != exp->saved_ip || + if (exp->tuple.dst.u3.ip != exp->saved_addr.ip || exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) { buflen = sprintf(buffer, "%pI4:%u", &newip, port); if (!mangle_packet(skb, protoff, dataoff, dptr, datalen,
@@ -485,13 +484,13 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int protoff,else rtp_addr->ip = ct->tuplehash[!dir].tuple.dst.u3.ip; - rtp_exp->saved_ip = rtp_exp->tuple.dst.u3.ip; + rtp_exp->saved_addr = rtp_exp->tuple.dst.u3; rtp_exp->tuple.dst.u3.ip = rtp_addr->ip; rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port; rtp_exp->dir = !dir; rtp_exp->expectfn = ip_nat_sip_expected; - rtcp_exp->saved_ip = rtcp_exp->tuple.dst.u3.ip; + rtcp_exp->saved_addr = rtcp_exp->tuple.dst.u3; rtcp_exp->tuple.dst.u3.ip = rtp_addr->ip; rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port; rtcp_exp->dir = !dir;
net/ipv4/netfilter/nf_nat_tftp.c +0 -1
@@ -11,7 +11,6 @@#include <net/netfilter/nf_conntrack_helper.h> #include <net/netfilter/nf_conntrack_expect.h> #include <net/netfilter/nf_nat_helper.h> -#include <net/netfilter/nf_nat_rule.h> #include <linux/netfilter/nf_conntrack_tftp.h> MODULE_AUTHOR ("Magnus Boden <[email protected]>" );
net/netfilter/Kconfig +24 -0
@@ -356,6 +356,30 @@ config NETFILTER_NETLINK_QUEUE_CT If this option is enabled, NFQUEUE can include Connection Tracking information together with the packet is the enqueued via NFNETLINK. +config NF_NAT + tristate + +config NF_NAT_NEEDED + bool + depends on NF_NAT + default y + +config NF_NAT_PROTO_DCCP + tristate + depends on NF_NAT && NF_CT_PROTO_DCCP + default NF_NAT && NF_CT_PROTO_DCCP + +config NF_NAT_PROTO_UDPLITE + tristate + depends on NF_NAT && NF_CT_PROTO_UDPLITE + default NF_NAT && NF_CT_PROTO_UDPLITE + +config NF_NAT_PROTO_SCTP + tristate + default NF_NAT && NF_CT_PROTO_SCTP + depends on NF_NAT && NF_CT_PROTO_SCTP + select LIBCRC32C + endif # NF_CONNTRACK # transparent proxy support
net/netfilter/Makefile +11 -0
@@ -43,6 +43,17 @@ obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o +nf_nat-y := nf_nat_core.o nf_nat_proto_unknown.o nf_nat_proto_common.o \ + nf_nat_proto_udp.o nf_nat_proto_tcp.o nf_nat_helper.o + +obj-$(CONFIG_NF_NAT) += nf_nat.o +obj-$(CONFIG_NF_NAT) += xt_nat.o + +# NAT protocols (nf_nat) +obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o +obj-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o +obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o + # transparent proxy support obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
net/netfilter/core.c +5 -0
@@ -273,6 +273,11 @@ EXPORT_SYMBOL_GPL(nfq_ct_nat_hook);#endif /* CONFIG_NF_CONNTRACK */ +#ifdef CONFIG_NF_NAT_NEEDED +void (*nf_nat_decode_session_hook)(struct sk_buff *,struct flowi *); +EXPORT_SYMBOL (nf_nat_decode_session_hook); +#endif +#ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_net_netfilter;EXPORT_SYMBOL (proc_net_netfilter);
net/netfilter/nf_conntrack_core.c +6 -0
@@ -55,6 +55,12 @@ int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct, const struct nlattr *attr) __read_mostly;EXPORT_SYMBOL_GPL (nfnetlink_parse_nat_setup_hook); +int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, +struct nf_conn *ct, +enum ip_conntrack_info ctinfo, +unsigned int protoff); +EXPORT_SYMBOL_GPL (nf_nat_seq_adjust_hook); +DEFINE_SPINLOCK (nf_conntrack_lock);EXPORT_SYMBOL_GPL (nf_conntrack_lock);
net/netfilter/nf_conntrack_netlink.c +29 -6
@@ -45,7 +45,7 @@#include <net/netfilter/nf_conntrack_timestamp.h> #ifdef CONFIG_NF_NAT_NEEDED #include <net/netfilter/nf_nat_core.h> -#include <net/netfilter/nf_nat_protocol.h> +#include <net/netfilter/nf_nat_l4proto.h> #include <net/netfilter/nf_nat_helper.h> #endif
@@ -1096,13 +1096,14 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct, const struct nlattr *attr) {typeof (nfnetlink_parse_nat_setup_hook) parse_nat_setup; +int err; parse_nat_setup =rcu_dereference (nfnetlink_parse_nat_setup_hook);if (!parse_nat_setup) {#ifdef CONFIG_MODULES rcu_read_unlock ();nfnl_unlock (); -if (request_module ("nf-nat-ipv4" ) <0 ) { +if (request_module ("nf-nat" ) <0 ) {nfnl_lock ();rcu_read_lock ();return -EOPNOTSUPP ;
@@ -1115,7 +1116,26 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct, return -EOPNOTSUPP; } -return parse_nat_setup (ct, manip, attr); + err =parse_nat_setup (ct, manip, attr); +if (err == -EAGAIN ) { +#ifdef CONFIG_MODULES +rcu_read_unlock (); +spin_unlock_bh (&nf_conntrack_lock); +nfnl_unlock (); +if (request_module ("nf-nat-%u" ,nf_ct_l3num (ct)) <0 ) { +nfnl_lock (); +spin_lock_bh (&nf_conntrack_lock); +rcu_read_lock (); +return -EOPNOTSUPP ; + } +nfnl_lock (); +spin_lock_bh (&nf_conntrack_lock); +rcu_read_lock (); +#else + err = -EOPNOTSUPP ; +#endif + } +return err; }#endif
@@ -1974,6 +1994,8 @@ nla_put_failure:return -1 ; } +static const union nf_inet_addr any_addr; +static int ctnetlink_exp_dump_expect (struct sk_buff *skb,const struct nf_conntrack_expect *exp)
@@ -2000,7 +2022,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, goto nla_put_failure;#ifdef CONFIG_NF_NAT_NEEDED -if (exp->saved_ip || exp->saved_proto.all) { +if (!nf_inet_addr_cmp (&exp->saved_addr, &any_addr) || + exp->saved_proto.all) { nest_parms =nla_nest_start (skb,CTA_EXPECT_NAT |NLA_F_NESTED );if (!nest_parms) goto nla_put_failure;
@@ -2009,7 +2032,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, goto nla_put_failure; nat_tuple.src.l3num =nf_ct_l3num (master); - nat_tuple.src.u3.ip = exp->saved_ip; + nat_tuple.src.u3 = exp->saved_addr; nat_tuple.dst.protonum =nf_ct_protonum (master); nat_tuple.src.u = exp->saved_proto;
@@ -2405,7 +2428,7 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr,if (err <0 )return err; - exp->saved_ip = nat_tuple.src.u3.ip; + exp->saved_addr = nat_tuple.src.u3; exp->saved_proto = nat_tuple.src.u; exp->dir =ntohl (nla_get_be32 (tb[CTA_EXPECT_NAT_DIR ]));
net/netfilter/nf_conntrack_proto_tcp.c +4 -4
@@ -505,10 +505,10 @@ static inline s16 nat_offset(const struct nf_conn *ct,return get_offset !=NULL ?get_offset (ct, dir, seq) :0 ; } -#define NAT_OFFSET (pf, ct, dir, seq) \ - (pf == NFPROTO_IPV4 ? nat_offset(ct, dir, seq) : 0) +#define NAT_OFFSET (ct, dir, seq) \ + (nat_offset(ct, dir, seq))#else -#define NAT_OFFSET (pf, ct, dir, seq) 0 +#define NAT_OFFSET (ct, dir, seq) 0#endif static bool tcp_in_window(const struct nf_conn *ct,
@@ -541,7 +541,7 @@ static bool tcp_in_window(const struct nf_conn *ct,tcp_sack (skb, dataoff, tcph, &sack);/* Take into account NAT sequence number mangling */ - receiver_offset =NAT_OFFSET (pf, ct, !dir, ack -1 ); + receiver_offset =NAT_OFFSET (ct, !dir, ack -1 ); ack -= receiver_offset; sack -= receiver_offset;
net/netfilter/nf_conntrack_sip.c +3 -3
@@ -946,11 +946,11 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,break ;#ifdef CONFIG_NF_NAT_NEEDED if (exp->tuple.src.l3num ==AF_INET && !direct_rtp && - (exp->saved_ip != exp->tuple.dst.u3.ip || + (exp->saved_addr.ip != exp->tuple.dst.u3.ip || exp->saved_proto.udp.port != exp->tuple.dst.u.udp.port) && ct->status &IPS_NAT_MASK ) { - daddr->ip = exp->saved_ip; - tuple.dst.u3.ip = exp->saved_ip; + daddr->ip = exp->saved_addr.ip; + tuple.dst.u3.ip = exp->saved_addr.ip; tuple.dst.u.udp.port = exp->saved_proto.udp.port; direct_rtp =1 ; }else
net/netfilter/nf_nat_core.c renamed from net/ipv4/netfilter/nf_nat_core.c +314 -285
919 lines not on this page · raw message
net/netfilter/nf_nat_helper.c renamed from net/ipv4/netfilter/nf_nat_helper.c +37 -63
31 lines not on this page · raw message
net/netfilter/nf_nat_proto_common.c renamed from net/ipv4/netfilter/nf_nat_proto_common.c +26 -28
54 lines not on this page · raw message
net/netfilter/nf_nat_proto_dccp.c renamed from net/ipv4/netfilter/nf_nat_proto_dccp.c +33 -23
56 lines not on this page · raw message
net/netfilter/nf_nat_proto_sctp.c renamed from net/ipv4/netfilter/nf_nat_proto_sctp.c +30 -23
53 lines not on this page · raw message
net/netfilter/nf_nat_proto_tcp.c renamed from net/ipv4/netfilter/nf_nat_proto_tcp.c +17 -23
Lines of this file are not shown. View the raw message.
net/netfilter/nf_nat_proto_udp.c renamed from net/ipv4/netfilter/nf_nat_proto_udp.c +18 -24
42 lines not on this page · raw message
net/netfilter/nf_nat_proto_udplite.c renamed from net/ipv4/netfilter/nf_nat_proto_udplite.c +33 -25
58 lines not on this page · raw message
net/netfilter/nf_nat_proto_unknown.c renamed from net/ipv4/netfilter/nf_nat_proto_unknown.c +9 -7
Lines of this file are not shown. View the raw message.
net/netfilter/xt_nat.c new file +167 -0
167 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
1.7.1
Part of the diff is not shown here. View the raw message.
PATCH 10/19 netfilter: ipv6: expand skb head in ip6_route_me_harder after oif change
In reply to [email protected]From: Patrick McHardy <[email protected]>
Expand the skb headroom if the oif changed due to rerouting similar to how IPv4 packets are handled.
--- net/ipv6/netfilter.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
net/ipv6/netfilter.c +8 -0
@@ -15,6 +15,7 @@ int ip6_route_me_harder(struct sk_buff *skb) {struct net *net =dev_net (skb_dst (skb)->dev);const struct ipv6hdr *iph =ipv6_hdr (skb); +unsigned int hh_len;struct dst_entry *dst;struct flowi6 fl6 = { .flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if :0 ,
@@ -47,6 +48,13 @@ int ip6_route_me_harder(struct sk_buff *skb) }#endif +/* Change in oif may mean change in hh_len. */ + hh_len =skb_dst (skb)->dev->hard_header_len; +if (skb_headroom (skb) < hh_len && +pskb_expand_head (skb,HH_DATA_ALIGN (hh_len -skb_headroom (skb)), +0 ,GFP_ATOMIC )) +return -1 ; +return 0 ; }EXPORT_SYMBOL (ip6_route_me_harder);
Signature · 1 line
1.7.1
PATCH 11/19 net: core: add function for incremental IPv6 pseudo header checksum updates
In reply to [email protected]From: Patrick McHardy <[email protected]>
Add inet_proto_csum_replace16 for incrementally updating IPv6 pseudo header checksums for IPv6 NAT.
--- include/net/checksum.h | 3 +++ net/core/utils.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 0 deletions(-)
include/net/checksum.h +3 -0
@@ -109,6 +109,9 @@ static inline void csum_replace2(__sum16 *sum, __be16 from, __be16 to)struct sk_buff ;extern void inet_proto_csum_replace4 (__sum16 *sum,struct sk_buff *skb,__be32 from,__be32 to,int pseudohdr); +extern void inet_proto_csum_replace16 (__sum16 *sum,struct sk_buff *skb, +const __be32 *from,const __be32 *to, +int pseudohdr); static inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb, __be16 from, __be16 to,
net/core/utils.c +20 -0
@@ -294,6 +294,26 @@ void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, }EXPORT_SYMBOL (inet_proto_csum_replace4); +void inet_proto_csum_replace16 (__sum16 *sum,struct sk_buff *skb, +const __be32 *from,const __be32 *to, +int pseudohdr) +{ +__be32 diff[] = { + ~from[0 ], ~from[1 ], ~from[2 ], ~from[3 ], + to[0 ], to[1 ], to[2 ], to[3 ], + }; +if (skb->ip_summed !=CHECKSUM_PARTIAL ) { + *sum =csum_fold (csum_partial (diff,sizeof (diff), + ~csum_unfold (*sum))); +if (skb->ip_summed ==CHECKSUM_COMPLETE && pseudohdr) + skb->csum = ~csum_partial (diff,sizeof (diff), + ~skb->csum); + }else if (pseudohdr) + *sum = ~csum_fold (csum_partial (diff,sizeof (diff), +csum_unfold (*sum))); +} +EXPORT_SYMBOL (inet_proto_csum_replace16); +int mac_pton (const char *s,u8 *mac) {int i;
Signature · 1 line
1.7.1
PATCH 12/19 netfilter: ipv6: add IPv6 NAT support
In reply to [email protected]From: Patrick McHardy <[email protected]>
--- include/linux/netfilter/nfnetlink_conntrack.h | 2 + include/net/netfilter/nf_nat_l3proto.h | 5 + include/net/netfilter/nf_nat_l4proto.h | 1 + include/net/netns/ipv6.h | 1 + net/core/secure_seq.c | 1 + net/ipv6/netfilter/Kconfig | 12 + net/ipv6/netfilter/Makefile | 4 + net/ipv6/netfilter/ip6table_nat.c | 321 ++++++++++++++++++++++++ net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 39 +++- net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 287 +++++++++++++++++++++ net/ipv6/netfilter/nf_nat_proto_icmpv6.c | 90 +++++++ 11 files changed, 761 insertions(+), 2 deletions(-) create mode 100644 net/ipv6/netfilter/ip6table_nat.c create mode 100644 net/ipv6/netfilter/nf_nat_l3proto_ipv6.c create mode 100644 net/ipv6/netfilter/nf_nat_proto_icmpv6.c
include/linux/netfilter/nfnetlink_conntrack.h +2 -0
@@ -147,6 +147,8 @@ enum ctattr_nat { CTA_NAT_V4_MAXIP,#define CTA_NAT_MAXIP CTA_NAT_V4_MAXIPCTA_NAT_PROTO , +CTA_NAT_V6_MINIP , +CTA_NAT_V6_MAXIP , __CTA_NAT_MAX };#define CTA_NAT_MAX (__CTA_NAT_MAX - 1)
include/net/netfilter/nf_nat_l3proto.h +5 -0
@@ -43,5 +43,10 @@ extern int nf_nat_icmp_reply_translation(struct sk_buff *skb,struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned int hooknum); +extern int nf_nat_icmpv6_reply_translation (struct sk_buff *skb, +struct nf_conn *ct, +enum ip_conntrack_info ctinfo, +unsigned int hooknum, +unsigned int hdrlen);#endif /* _NF_NAT_L3PROTO_H */
include/net/netfilter/nf_nat_l4proto.h +1 -0
@@ -51,6 +51,7 @@ extern const struct nf_nat_l4proto *__nf_nat_l4proto_find(u8 l3proto, u8 l4protoextern const struct nf_nat_l4proto nf_nat_l4proto_tcp;extern const struct nf_nat_l4proto nf_nat_l4proto_udp;extern const struct nf_nat_l4proto nf_nat_l4proto_icmp; +extern const struct nf_nat_l4proto nf_nat_l4proto_icmpv6;extern const struct nf_nat_l4proto nf_nat_l4proto_unknown; extern bool nf_nat_l4proto_in_range(const struct nf_conntrack_tuple *tuple,
include/net/netns/ipv6.h +1 -0
@@ -42,6 +42,7 @@ struct netns_ipv6 {#ifdef CONFIG_SECURITY struct xt_table *ip6table_security;#endif +struct xt_table *ip6table_nat;#endif struct rt6_info *ip6_null_entry;struct rt6_statistics *rt6_stats;
net/core/secure_seq.c +1 -0
@@ -76,6 +76,7 @@ u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, return hash[0]; } +EXPORT_SYMBOL (secure_ipv6_port_ephemeral);#endif #ifdef CONFIG_INET
net/ipv6/netfilter/Kconfig +12 -0
@@ -25,6 +25,18 @@ config NF_CONNTRACK_IPV6 To compile it as a module, choose M here. If unsure, say N. +config NF_NAT_IPV6 + tristate "IPv6 NAT" + depends on NF_CONNTRACK_IPV6 + depends on NETFILTER_ADVANCED + select NF_NAT + help + The IPv6 NAT option allows masquerading, port forwarding and other + forms of full Network Address Port Translation. It is controlled by + the `nat' table in ip6tables, see the man page for ip6tables(8). + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_IPTABLES tristate "IP6 tables support (required for filtering)" depends on INET && IPV6
net/ipv6/netfilter/Makefile +4 -0
@@ -8,6 +8,7 @@ obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o +obj-$(CONFIG_NF_NAT_IPV6) += ip6table_nat.o # objects for l3 independent conntrack nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o
@@ -15,6 +16,9 @@ nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o # l3 independent conntrack obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o +nf_nat_ipv6-y := nf_nat_l3proto_ipv6.o nf_nat_proto_icmpv6.o +obj-$(CONFIG_NF_NAT_IPV6) += nf_nat_ipv6.o + # defrag nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o
net/ipv6/netfilter/ip6table_nat.c new file +321 -0
321 lines not on this page · raw message
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +37 -2
@@ -28,6 +28,7 @@#include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_zones.h> #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> +#include <net/netfilter/nf_nat_helper.h> #include <net/netfilter/ipv6/nf_defrag_ipv6.h> #include <net/netfilter/nf_log.h>
@@ -142,6 +143,36 @@ static unsigned int ipv6_confirm(unsigned int hooknum,const struct net_device *out, int (*okfn)(struct sk_buff *)) { + struct nf_conn *ct; +enum ip_conntrack_info ctinfo; +unsigned char pnum =ipv6_hdr (skb)->nexthdr; +int protoff; +__be16 frag_off; + + ct =nf_ct_get (skb, &ctinfo); +if (!ct || ctinfo ==IP_CT_RELATED_REPLY ) + goto out; + + protoff =ipv6_skip_exthdr (skb,sizeof (struct ipv6hdr ), &pnum, + &frag_off); +if (protoff <0 || (frag_off &ntohs (~0x7 )) !=0 ) { +pr_debug ("proto header not found\n" ); + goto out; + } + +/* adjust seqs for loopback traffic only in outgoing direction */ +if (test_bit (IPS_SEQ_ADJUST_BIT , &ct->status) && + !nf_is_loopback_packet (skb)) { +typeof (nf_nat_seq_adjust_hook) seq_adjust; + + seq_adjust =rcu_dereference (nf_nat_seq_adjust_hook); +if (!seq_adjust || + !seq_adjust (skb, ct, ctinfo, protoff)) { +NF_CT_STAT_INC_ATOMIC (nf_ct_net (ct), drop); +return NF_DROP ; + } + } +out:/* We've seen it coming out the other side: confirm it */ return nf_conntrack_confirm (skb); }
@@ -169,10 +200,14 @@ static unsigned int __ipv6_conntrack_in(struct net *net, }/* Conntrack helpers need the entire reassembled packet in the -* POST_ROUTING hook. +* POST_ROUTING hook. In case of unconfirmed connections NAT +* might reassign a helper, so the entire packet is also +* required. */ ct =nf_ct_get (reasm, &ctinfo); -if (ct !=NULL &&test_bit (IPS_HELPER_BIT , &ct->status)) { +if (ct !=NULL && + (test_bit (IPS_HELPER_BIT , &ct->status) || + !nf_ct_is_confirmed (ct))) {nf_conntrack_get_reasm (skb); NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm, (struct net_device *)in,
net/ipv6/netfilter/nf_nat_l3proto_ipv6.c new file +287 -0
287 lines not on this page · raw message
net/ipv6/netfilter/nf_nat_proto_icmpv6.c new file +90 -0
90 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH 13/19 netfilter: ip6tables: add MASQUERADE target
In reply to [email protected]From: Patrick McHardy <[email protected]>
--- include/net/addrconf.h | 2 +- net/ipv4/netfilter/ipt_MASQUERADE.c | 3 +- net/ipv6/addrconf.c | 2 +- net/ipv6/netfilter/Kconfig | 12 +++ net/ipv6/netfilter/Makefile | 1 + net/ipv6/netfilter/ip6t_MASQUERADE.c | 135 ++++++++++++++++++++++++++++++++++ 6 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 net/ipv6/netfilter/ip6t_MASQUERADE.c
include/net/addrconf.h +1 -1
@@ -78,7 +78,7 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, int strict);extern int ipv6_dev_get_saddr (struct net *net, -struct net_device *dev, +const struct net_device *dev,const struct in6_addr *daddr,unsigned int srcprefs,struct in6_addr *saddr);
net/ipv4/netfilter/ipt_MASQUERADE.c +2 -1
@@ -99,7 +99,8 @@ device_cmp(struct nf_conn *i, void *ifindex)if (!nat)return 0 ; - +if (nf_ct_l3num (i) !=NFPROTO_IPV4 ) +return 0 ;return nat->masq_index == (int )(long )ifindex; }
net/ipv6/addrconf.c +1 -1
@@ -1095,7 +1095,7 @@ out:return ret; } -int ipv6_dev_get_saddr (struct net *net,struct net_device *dst_dev, +int ipv6_dev_get_saddr (struct net *net,const struct net_device *dst_dev,const struct in6_addr *daddr,unsigned int prefs,struct in6_addr *saddr) {
net/ipv6/netfilter/Kconfig +12 -0
@@ -144,6 +144,18 @@ config IP6_NF_TARGET_HL (e.g. when running oldconfig). It selects CONFIG_NETFILTER_XT_TARGET_HL. +config IP6_NF_TARGET_MASQUERADE + tristate "MASQUERADE target support" + depends on NF_NAT_IPV6 + help + Masquerading is a special case of NAT: all outgoing connections are + changed to seem to come from a particular interface's address, and + if the interface goes down, those connections are lost. This is + only useful for dialup accounts with dynamic IP address (ie. your IP + address will be different on next dialup). + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_FILTER tristate "Packet filtering" default m if NETFILTER_ADVANCED=n
net/ipv6/netfilter/Makefile +1 -0
@@ -34,4 +34,5 @@ obj-$(CONFIG_IP6_NF_MATCH_RPFILTER) += ip6t_rpfilter.o obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o # targets +obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
net/ipv6/netfilter/ip6t_MASQUERADE.c new file +135 -0
135 lines not on this page · raw message
Signature · 1 line
1.7.1
Pablo Neira Ayuso
maintainerRe: [PATCH 13/19] netfilter: ip6tables: add MASQUERADE target
Hi Patrick,
Quoted 12 lines · On Thu, Aug 09, 2012 at 10:08:57PM +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
Signed-off-by Patrick McHardy <[email protected]>--- include/net/addrconf.h | 2 +- net/ipv4/netfilter/ipt_MASQUERADE.c | 3 +- net/ipv6/addrconf.c | 2 +- net/ipv6/netfilter/Kconfig | 12 +++ net/ipv6/netfilter/Makefile | 1 + net/ipv6/netfilter/ip6t_MASQUERADE.c | 135 ++++++++++++++++++++++++++++++++++ 6 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 net/ipv6/netfilter/ip6t_MASQUERADE.c
Please, add this chunk to this patch:
(quoted diff) +0 -0
b/include/net/netfilter/nf_nat.h
index 1752f133..bd8eea7 100644
include/net/netfilter/nf_nat.h +3 -1
@@ -43,7 +43,9 @@ struct nf_conn_nat {struct nf_conn *ct;union nf_conntrack_nat_help help;#if defined(CONFIG_IP_NF_TARGET_MASQUERADE ) || \ - defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE ) + defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE ) || \ + defined(CONFIG_IP6_NF_TARGET_MASQUERADE ) || \ + defined(CONFIG_IP6_NF_TARGET_MASQUERADE_MODULE )int masq_index;#endif };
Otherwise, compilation breaks with:
* IPv4 NAT is disabled
* IPv6 NAT enabled.
And yes, that pile of ifdefs is really ugly, I wonder if they are worth for saving 4 bytes. I think most vendors usually include MASQUERADE support if NAT is enabled.
It seems we have the tradition of keeping several similar compile time options in Netfilter to optimize memory in several situations (at the cost of polluting the code with ifdefs). Probably we can think of getting rid of them.
Quoted 221 lines
include/net/addrconf.h +1
-1@@ -78,7 +78,7 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, int strict);extern int ipv6_dev_get_saddr (struct net *net, -struct net_device *dev, +const struct net_device *dev,const struct in6_addr *daddr,unsigned int srcprefs,struct in6_addr *saddr);net/ipv4/netfilter/ipt_MASQUERADE.c +2
-1@@ -99,7 +99,8 @@ device_cmp(struct nf_conn *i, void *ifindex)if (!nat)return 0 ; - +if (nf_ct_l3num (i) !=NFPROTO_IPV4 ) +return 0 ;return nat->masq_index == (int )(long )ifindex; }net/ipv6/addrconf.c +1
-1@@ -1095,7 +1095,7 @@ out:return ret; } -int ipv6_dev_get_saddr (struct net *net,struct net_device *dst_dev, +int ipv6_dev_get_saddr (struct net *net,const struct net_device *dst_dev,const struct in6_addr *daddr,unsigned int prefs,struct in6_addr *saddr) {net/ipv6/netfilter/Kconfig +12
-0@@ -144,6 +144,18 @@ config IP6_NF_TARGET_HL (e.g. when running oldconfig). It selects CONFIG_NETFILTER_XT_TARGET_HL. +config IP6_NF_TARGET_MASQUERADE + tristate "MASQUERADE target support" + depends on NF_NAT_IPV6 + help + Masquerading is a special case of NAT: all outgoing connections are + changed to seem to come from a particular interface's address, and + if the interface goes down, those connections are lost. This is + only useful for dialup accounts with dynamic IP address (ie. your IP + address will be different on next dialup). + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_FILTER tristate "Packet filtering" default m if NETFILTER_ADVANCED=nnet/ipv6/netfilter/Makefile +1
-0@@ -34,4 +34,5 @@ obj-$(CONFIG_IP6_NF_MATCH_RPFILTER) += ip6t_rpfilter.o obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o # targets +obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.onet/ipv6/netfilter/ip6t_MASQUERADE.c new file +135
-0@@ -0,0 +1,135 @@ +/* +* Copyright (c) 2011 Patrick McHardy <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* Based on Rusty Russell's IPv6 MASQUERADE target. Development of IPv6 +* NAT funded by Astaro. +*/ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/ipv6.h> +#include <linux/netfilter.h> +#include <linux/netfilter_ipv6.h> +#include <linux/netfilter/x_tables.h> +#include <net/netfilter/nf_nat.h> +#include <net/addrconf.h> +#include <net/ipv6.h> + +static unsigned int +masquerade_tg6 (struct sk_buff *skb,const struct xt_action_param *par) +{ +const struct nf_nat_range *range = par->targinfo; +enum ip_conntrack_info ctinfo; +struct in6_addr src; +struct nf_conn *ct; +struct nf_nat_range newrange; + + ct =nf_ct_get (skb, &ctinfo); +NF_CT_ASSERT (ct && (ctinfo ==IP_CT_NEW || ctinfo ==IP_CT_RELATED || + ctinfo ==IP_CT_RELATED_REPLY )); + +if (ipv6_dev_get_saddr (dev_net (par->out), par->out, + &ipv6_hdr (skb)->daddr,0 , &src) <0 ) +return NF_DROP ; + +nfct_nat (ct)->masq_index = par->out->ifindex; + + newrange.flags = range->flags |NF_NAT_RANGE_MAP_IPS ; + newrange.min_addr.in6 = src; + newrange.max_addr.in6 = src; + newrange.min_proto = range->min_proto; + newrange.max_proto = range->max_proto; + +return nf_nat_setup_info (ct, &newrange,NF_NAT_MANIP_SRC ); +} + +static int masquerade_tg6_checkentry (const struct xt_tgchk_param *par) +{ +const struct nf_nat_range *range = par->targinfo; + +if (range->flags &NF_NAT_RANGE_MAP_IPS ) +return -EINVAL ; +return 0 ; +} + +static int device_cmp (struct nf_conn *ct,void *ifindex) +{ +const struct nf_conn_nat *nat =nfct_nat (ct); + +if (!nat) +return 0 ; +if (nf_ct_l3num (ct) !=NFPROTO_IPV6 ) +return 0 ; +return nat->masq_index == (int )(long )ifindex; +} + +static int masq_device_event (struct notifier_block *this, +unsigned long event,void *ptr) +{ +const struct net_device *dev = ptr; +struct net *net =dev_net (dev); + +if (event ==NETDEV_DOWN ) +nf_ct_iterate_cleanup (net, device_cmp, + (void *)(long )dev->ifindex); + +return NOTIFY_DONE ; +} + +static struct notifier_block masq_dev_notifier = { + .notifier_call = masq_device_event, +}; + +static int masq_inet_event (struct notifier_block *this, +unsigned long event,void *ptr) +{ +struct inet6_ifaddr *ifa = ptr; + +return masq_device_event (this, event, ifa->idev->dev); +} + +static struct notifier_block masq_inet_notifier = { + .notifier_call = masq_inet_event, +}; + +static struct xt_target masquerade_tg6_reg__read_mostly = { + .name ="MASQUERADE" , + .family =NFPROTO_IPV6 , + .checkentry = masquerade_tg6_checkentry, + .target = masquerade_tg6, + .targetsize =sizeof (struct nf_nat_range ), + .table ="nat" , + .hooks =1 <<NF_INET_POST_ROUTING , + .me =THIS_MODULE , +}; + +static int __init masquerade_tg6_init (void ) +{ +int err; + + err =xt_register_target (&masquerade_tg6_reg); +if (err ==0 ) { +register_netdevice_notifier (&masq_dev_notifier); +register_inet6addr_notifier (&masq_inet_notifier); + } + +return err; +} +static void __exit masquerade_tg6_exit(void) +{ +unregister_inet6addr_notifier (&masq_inet_notifier); +unregister_netdevice_notifier (&masq_dev_notifier); +xt_unregister_target (&masquerade_tg6_reg); +} + +module_init (masquerade_tg6_init); +module_exit (masquerade_tg6_exit); + +MODULE_LICENSE ("GPL" ); +MODULE_AUTHOR ("Patrick McHardy <[email protected]>" ); +MODULE_DESCRIPTION ("Xtables: automatic address SNAT" );Signature · 6 lines
1.7.1 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 13/19] netfilter: ip6tables: add MASQUERADE target
Quoted 24 lines · Pablo Neira Ayuso
Hi Patrick,
Quoted 2 lines · On Thu, Aug 09, 2012 at 10:08:57PM +0200, [email protected] wrote:
From: Patrick McHardy <[email protected]>
Please, add this chunk to this patch:
include/net/netfilter/nf_nat.h +3
-1@@ -43,7 +43,9 @@ struct nf_conn_nat {struct nf_conn *ct;union nf_conntrack_nat_help help;#if defined(CONFIG_IP_NF_TARGET_MASQUERADE ) || \ - defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE ) + defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE ) || \ + defined(CONFIG_IP6_NF_TARGET_MASQUERADE ) || \ + defined(CONFIG_IP6_NF_TARGET_MASQUERADE_MODULE )int masq_index;#endif };
Quoted 4 lines
Otherwise, compilation breaks with:
* IPv4 NAT is disabled
* IPv6 NAT enabled.
Fixed, thanks.
Quoted 9 lines
And yes, that pile of ifdefs is really ugly, I wonder if they are worth for saving 4 bytes. I think most vendors usually include MASQUERADE support if NAT is enabled.
It seems we have the tradition of keeping several similar compile time options in Netfilter to optimize memory in several situations (at the cost of polluting the code with ifdefs). Probably we can think of getting rid of them.
Well, vendors maybe, but what about embedded systems? I have some which are *really* short on memory. They limit conntrack to very few entries though, so it doesn't make that much of a difference.
PATCH 14/19 netfilter: ip6tables: add REDIRECT target
In reply to [email protected]From: Patrick McHardy <[email protected]>
--- net/ipv6/netfilter/Kconfig | 11 ++++ net/ipv6/netfilter/Makefile | 1 + net/ipv6/netfilter/ip6t_REDIRECT.c | 98 ++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 0 deletions(-) create mode 100644 net/ipv6/netfilter/ip6t_REDIRECT.c
net/ipv6/netfilter/Kconfig +11 -0
@@ -156,6 +156,17 @@ config IP6_NF_TARGET_MASQUERADE To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_TARGET_REDIRECT + tristate "REDIRECT target support" + depends on NF_NAT_IPV6 + help + REDIRECT is a special case of NAT: all incoming connections are + mapped onto the incoming interface's address, causing the packets to + come to the local machine instead of passing through. This is + useful for transparent proxies. + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_FILTER tristate "Packet filtering" default m if NETFILTER_ADVANCED=n
net/ipv6/netfilter/Makefile +1 -0
@@ -35,4 +35,5 @@ obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o # targets obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o +obj-$(CONFIG_IP6_NF_TARGET_REDIRECT) += ip6t_REDIRECT.o obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
net/ipv6/netfilter/ip6t_REDIRECT.c new file +98 -0
98 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH 15/19 netfilter: ip6tables: add NETMAP target
In reply to [email protected]From: Patrick McHardy <[email protected]>
--- net/ipv6/netfilter/Kconfig | 10 ++++ net/ipv6/netfilter/Makefile | 1 + net/ipv6/netfilter/ip6t_NETMAP.c | 94 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 0 deletions(-) create mode 100644 net/ipv6/netfilter/ip6t_NETMAP.c
net/ipv6/netfilter/Kconfig +10 -0
@@ -156,6 +156,16 @@ config IP6_NF_TARGET_MASQUERADE To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_TARGET_NETMAP + tristate "NETMAP target support" + depends on NF_NAT_IPV6 + help + NETMAP is an implementation of static 1:1 NAT mapping of network + addresses. It maps the network address part, while keeping the host + address part intact. + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_TARGET_REDIRECT tristate "REDIRECT target support" depends on NF_NAT_IPV6
net/ipv6/netfilter/Makefile +1 -0
@@ -35,5 +35,6 @@ obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o # targets obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o +obj-$(CONFIG_IP6_NF_TARGET_NETMAP) += ip6t_NETMAP.o obj-$(CONFIG_IP6_NF_TARGET_REDIRECT) += ip6t_REDIRECT.o obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
net/ipv6/netfilter/ip6t_NETMAP.c new file +94 -0
94 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH 16/19 netfilter: nf_nat: support IPv6 in FTP NAT helper
In reply to [email protected]From: Patrick McHardy <[email protected]>
---
net/ipv4/netfilter/Kconfig | 5 -----
net/ipv4/netfilter/Makefile | 1 -
net/netfilter/Kconfig | 5 +++++
net/netfilter/Makefile | 3 +++
net/netfilter/nf_conntrack_ftp.c | 3 +--
net/{ipv4 => }/netfilter/nf_nat_ftp.c | 30 ++++++++++++++++++------------
6 files changed, 27 insertions(+), 20 deletions(-)
rename net/{ipv4 => }/netfilter/nf_nat_ftp.c (82%)net/ipv4/netfilter/Kconfig +0 -5
@@ -220,11 +220,6 @@ config NF_NAT_PROTO_GRE tristate depends on NF_NAT_IPV4 && NF_CT_PROTO_GRE -config NF_NAT_FTP - tristate - depends on NF_CONNTRACK && NF_NAT_IPV4 - default NF_NAT_IPV4 && NF_CONNTRACK_FTP - config NF_NAT_IRC tristate depends on NF_CONNTRACK && NF_NAT_IPV4
net/ipv4/netfilter/Makefile +0 -1
@@ -21,7 +21,6 @@ obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o # NAT helpers (nf_conntrack) obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o -obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
net/netfilter/Kconfig +5 -0
@@ -380,6 +380,11 @@ config NF_NAT_PROTO_SCTP depends on NF_NAT && NF_CT_PROTO_SCTP select LIBCRC32C +config NF_NAT_FTP + tristate + depends on NF_CONNTRACK && NF_NAT + default NF_NAT && NF_CONNTRACK_FTP + endif # NF_CONNTRACK # transparent proxy support
net/netfilter/Makefile +3 -0
@@ -54,6 +54,9 @@ obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o obj-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o +# NAT helpers +obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o + # transparent proxy support obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
net/netfilter/nf_conntrack_ftp.c +1 -2
@@ -488,8 +488,7 @@ static int help(struct sk_buff *skb,/* Now, NAT might want to mangle the packet, and register the * (possibly changed) expectation itself. */ nf_nat_ftp =rcu_dereference (nf_nat_ftp_hook); -if (nf_nat_ftp &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && - ct->status &IPS_NAT_MASK ) +if (nf_nat_ftp && ct->status &IPS_NAT_MASK ) ret =nf_nat_ftp (skb, ctinfo, search[dir][i].ftptype, protoff, matchoff, matchlen, exp);else {
net/netfilter/nf_nat_ftp.c renamed from net/ipv4/netfilter/nf_nat_ftp.c +18 -12
@@ -10,7 +10,7 @@#include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/ip.h> +#include <linux/inet.h> #include <linux/tcp.h> #include <linux/netfilter_ipv4.h> #include <net/netfilter/nf_nat.h>
@@ -26,22 +26,27 @@ MODULE_ALIAS("ip_nat_ftp");/* FIXME: Time out? --RR */ -static int nf_nat_ftp_fmt_cmd (enum nf_ct_ftp_type type, +static int nf_nat_ftp_fmt_cmd (struct nf_conn *ct,enum nf_ct_ftp_type type,char *buffer,size_t buflen, -__be32 addr,u16 port) +union nf_inet_addr *addr,u16 port) {switch (type) {case NF_CT_FTP_PORT :case NF_CT_FTP_PASV :return snprintf (buffer, buflen,"%u,%u,%u,%u,%u,%u" , - ((unsigned char *)&addr)[0 ], - ((unsigned char *)&addr)[1 ], - ((unsigned char *)&addr)[2 ], - ((unsigned char *)&addr)[3 ], + ((unsigned char *)&addr->ip)[0 ], + ((unsigned char *)&addr->ip)[1 ], + ((unsigned char *)&addr->ip)[2 ], + ((unsigned char *)&addr->ip)[3 ], port >>8 , port &0xFF );case NF_CT_FTP_EPRT : -return snprintf (buffer, buflen,"|1|%pI4|%u|" , &addr, port); +if (nf_ct_l3num (ct) ==NFPROTO_IPV4 ) +return snprintf (buffer, buflen,"|1|%pI4|%u|" , + &addr->ip, port); +else +return snprintf (buffer, buflen,"|2|%pI6|%u|" , + &addr->ip6, port);case NF_CT_FTP_EPSV :return snprintf (buffer, buflen,"|||%u|" , port); }
@@ -59,17 +64,17 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb,unsigned int matchlen, struct nf_conntrack_expect *exp) { - __be32 newip; + union nf_inet_addr newaddr;u_int16_t port;int dir =CTINFO2DIR (ctinfo);struct nf_conn *ct = exp->master; -char buffer[sizeof ("|1|255.255.255.255|65535|" )]; +char buffer[sizeof ("|1||65535|" ) +INET6_ADDRSTRLEN ];unsigned int buflen;pr_debug ("FTP_NAT: type %i, off %u len %u\n" , type, matchoff, matchlen);/* Connection will come from wherever this packet goes, hence !dir */ - newip = ct->tuplehash[!dir].tuple.dst.u3.ip; + newaddr = ct->tuplehash[!dir].tuple.dst.u3; exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; exp->dir = !dir;
@@ -94,7 +99,8 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb,if (port ==0 )return NF_DROP ; - buflen =nf_nat_ftp_fmt_cmd (type, buffer,sizeof (buffer), newip, port); + buflen =nf_nat_ftp_fmt_cmd (ct, type, buffer,sizeof (buffer), + &newaddr, port);if (!buflen) goto out;
Signature · 1 line
1.7.1
PATCH 17/19 netfilter: nf_nat: support IPv6 in amanda NAT helper
In reply to [email protected]From: Patrick McHardy <[email protected]>
---
net/ipv4/netfilter/Kconfig | 5 -----
net/ipv4/netfilter/Makefile | 1 -
net/netfilter/Kconfig | 5 +++++
net/netfilter/Makefile | 1 +
net/netfilter/nf_conntrack_amanda.c | 3 +--
net/{ipv4 => }/netfilter/nf_nat_amanda.c | 0
6 files changed, 7 insertions(+), 8 deletions(-)
rename net/{ipv4 => }/netfilter/nf_nat_amanda.c (100%)net/ipv4/netfilter/Kconfig +0 -5
@@ -230,11 +230,6 @@ config NF_NAT_TFTP depends on NF_CONNTRACK && NF_NAT_IPV4 default NF_NAT_IPV4 && NF_CONNTRACK_TFTP -config NF_NAT_AMANDA - tristate - depends on NF_CONNTRACK && NF_NAT_IPV4 - default NF_NAT_IPV4 && NF_CONNTRACK_AMANDA - config NF_NAT_PPTP tristate depends on NF_CONNTRACK && NF_NAT_IPV4
net/ipv4/netfilter/Makefile +0 -1
@@ -20,7 +20,6 @@ obj-$(CONFIG_NF_NAT_IPV4) += nf_nat_ipv4.o obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o # NAT helpers (nf_conntrack) -obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
net/netfilter/Kconfig +5 -0
@@ -380,6 +380,11 @@ config NF_NAT_PROTO_SCTP depends on NF_NAT && NF_CT_PROTO_SCTP select LIBCRC32C +config NF_NAT_AMANDA + tristate + depends on NF_CONNTRACK && NF_NAT + default NF_NAT && NF_CONNTRACK_AMANDA + config NF_NAT_FTP tristate depends on NF_CONNTRACK && NF_NAT
net/netfilter/Makefile +1 -0
@@ -55,6 +55,7 @@ obj-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o # NAT helpers +obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o # transparent proxy support
net/netfilter/nf_conntrack_amanda.c +1 -2
@@ -155,8 +155,7 @@ static int amanda_help(struct sk_buff *skb, IPPROTO_TCP, NULL, &port); nf_nat_amanda =rcu_dereference (nf_nat_amanda_hook); -if (nf_nat_amanda &&nf_ct_l3num (ct) ==NFPROTO_IPV4 && - ct->status &IPS_NAT_MASK ) +if (nf_nat_amanda && ct->status &IPS_NAT_MASK ) ret =nf_nat_amanda (skb, ctinfo, protoff, off - dataoff, len, exp);else if (nf_ct_expect_related (exp) !=0 )
net/netfilter/nf_nat_amanda.c renamed from net/ipv4/netfilter/nf_nat_amanda.c +0 -0
Signature · 1 line
1.7.1
PATCH 18/19 netfilter: nf_nat: support IPv6 in SIP NAT helper
In reply to [email protected]From: Patrick McHardy <[email protected]>
Add IPv6 support to the SIP NAT helper. There are no functional differences to IPv4 NAT, just different formats for addresses.
---
include/linux/netfilter/nf_conntrack_sip.h | 9 +-
net/ipv4/netfilter/Kconfig | 5 -
net/ipv4/netfilter/Makefile | 1 -
net/netfilter/Kconfig | 5 +
net/netfilter/Makefile | 1 +
net/netfilter/nf_conntrack_sip.c | 68 ++++++------
net/{ipv4 => }/netfilter/nf_nat_sip.c | 172 ++++++++++++++++------------
7 files changed, 145 insertions(+), 116 deletions(-)
rename net/{ipv4 => }/netfilter/nf_nat_sip.c (76%)include/linux/netfilter/nf_conntrack_sip.h +4 -5
@@ -99,10 +99,8 @@ enum sip_header_types {enum sdp_header_types {SDP_HDR_UNSPEC ,SDP_HDR_VERSION , -SDP_HDR_OWNER_IP4 , -SDP_HDR_CONNECTION_IP4 , -SDP_HDR_OWNER_IP6 , -SDP_HDR_CONNECTION_IP6 , +SDP_HDR_OWNER , +SDP_HDR_CONNECTION ,SDP_HDR_MEDIA , };
@@ -111,7 +109,8 @@ extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb,unsigned int dataoff, const char **dptr, unsigned int *datalen); -extern void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb,s16 off); +extern void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, +unsigned int protoff,s16 off); extern unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb, unsigned int protoff, unsigned int dataoff,
net/ipv4/netfilter/Kconfig +0 -5
@@ -241,11 +241,6 @@ config NF_NAT_H323 depends on NF_CONNTRACK && NF_NAT_IPV4 default NF_NAT_IPV4 && NF_CONNTRACK_H323 -config NF_NAT_SIP - tristate - depends on NF_CONNTRACK && NF_NAT_IPV4 - default NF_NAT_IPV4 && NF_CONNTRACK_SIP - # mangle + specific targets config IP_NF_MANGLE tristate "Packet mangling"
net/ipv4/netfilter/Makefile +0 -1
@@ -23,7 +23,6 @@ obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o -obj-$(CONFIG_NF_NAT_SIP) += nf_nat_sip.o obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o
net/netfilter/Kconfig +5 -0
@@ -390,6 +390,11 @@ config NF_NAT_FTP depends on NF_CONNTRACK && NF_NAT default NF_NAT && NF_CONNTRACK_FTP +config NF_NAT_SIP + tristate + depends on NF_CONNTRACK && NF_NAT + default NF_NAT && NF_CONNTRACK_SIP + endif # NF_CONNTRACK # transparent proxy support
net/netfilter/Makefile +1 -0
@@ -57,6 +57,7 @@ obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o # NAT helpers obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o +obj-$(CONFIG_NF_NAT_SIP) += nf_nat_sip.o # transparent proxy support obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
net/netfilter/nf_conntrack_sip.c +34 -34
160 lines not on this page · raw message
net/netfilter/nf_nat_sip.c renamed from net/ipv4/netfilter/nf_nat_sip.c +101 -71
382 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH 19/19 netfilter: ip6tables: add stateless IPv6-to-IPv6 Network Prefix Translation target
In reply to [email protected]From: Patrick McHardy <[email protected]>
--- include/linux/netfilter_ipv6/Kbuild | 1 + include/linux/netfilter_ipv6/ip6t_NPT.h | 16 +++ net/ipv6/netfilter/Kconfig | 9 ++ net/ipv6/netfilter/Makefile | 1 + net/ipv6/netfilter/ip6t_NPT.c | 165 +++++++++++++++++++++++++++++++ 5 files changed, 192 insertions(+), 0 deletions(-) create mode 100644 include/linux/netfilter_ipv6/ip6t_NPT.h create mode 100644 net/ipv6/netfilter/ip6t_NPT.c
include/linux/netfilter_ipv6/Kbuild +1 -0
@@ -1,6 +1,7 @@ header-y += ip6_tables.h header-y += ip6t_HL.h header-y += ip6t_LOG.h +header-y += ip6t_NPT.h header-y += ip6t_REJECT.h header-y += ip6t_ah.h header-y += ip6t_frag.h
include/linux/netfilter_ipv6/ip6t_NPT.h new file +16 -0
@@ -0,0 +1,16 @@ +#ifndef __NETFILTER_IP6T_NPT +#define __NETFILTER_IP6T_NPT + +#include <linux/types.h> +#include <linux/netfilter.h> + +struct ip6t_npt_tginfo { +union nf_inet_addr src_pfx; +union nf_inet_addr dst_pfx; +__u8 src_pfx_len; +__u8 dst_pfx_len; +/* Used internally by the kernel */ +__sum16 adjustment; +}; + +#endif /* __NETFILTER_IP6T_NPT */
net/ipv6/netfilter/Kconfig +9 -0
@@ -177,6 +177,15 @@ config IP6_NF_TARGET_REDIRECT To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_TARGET_NPT + tristate "NPT (Network Prefix translation) target support" + depends on NETFILTER_ADVANCED + help + This option adda `SNPT' and `DNPT' target, which perform stateless + IPv6-to-IPv6 Network Prefix Translation (RFC 6296). + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_FILTER tristate "Packet filtering" default m if NETFILTER_ADVANCED=n
net/ipv6/netfilter/Makefile +1 -0
@@ -36,5 +36,6 @@ obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o # targets obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o obj-$(CONFIG_IP6_NF_TARGET_NETMAP) += ip6t_NETMAP.o +obj-$(CONFIG_IP6_NF_TARGET_NPT) += ip6t_NPT.o obj-$(CONFIG_IP6_NF_TARGET_REDIRECT) += ip6t_REDIRECT.o obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
net/ipv6/netfilter/ip6t_NPT.c new file +165 -0
165 lines not on this page · raw message
Signature · 1 line
1.7.1
Re: [PATCH 19/19] netfilter: ip6tables: add stateless IPv6-to-IPv6 Network Prefix Translation target
net/ipv6/netfilter/Kconfig config IP6_NF_TARGET_REDIRECT · line 185
Quoted 6 lines · On Thursday 2012-08-09 22:09, [email protected] wrote:
net/ipv6/netfilter/Kconfig +6
-0+config IP6_NF_TARGET_NPT + tristate "NPT (Network Prefix translation) target support" + depends on NETFILTER_ADVANCED + help + This option adda `SNPT' and `DNPT' target, which perform stateless + IPv6-to-IPv6 Network Prefix Translation (RFC 6296).
Fixes/suggestion in the help text (near "adda" and subsequent).
config IP6_NF_TARGET_NPT
tristate "NPT (Network Prefix translation) target support" depends on NETFILTER_ADVANCED
---help---
This option adds the "SNPT" and "DNPT" targets, which perform stateless IPv6-to-IPv6 Network Prefix Translation per RFC 6296.
Quoted 7 lines
+/*
+ * Copyright (c) 2011, 2012 Patrick McHardy <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
GNU sometimes has a strange way of expressing their (C) lines, listing all years separately, as if "1989-1991,1994-1999,2001-2005" was not sufficient. In your case, would "2011-2012" work?
Any objection to adding a "(or later)" clause to the set?
net/ipv6/netfilter/ip6t_NPT.c line 43
Quoted 8 lines
net/ipv6/netfilter/ip6t_NPT.c new file +8
-0+static int ip6t_npt_checkentry (const struct xt_tgchk_param *par) +{ +struct ip6t_npt_tginfo *npt = par->targinfo; +__sum16 src_sum =0 , dst_sum =0 ; +unsigned int i; + +if (npt->src_pfx_len >64 || npt->dst_pfx_len >64 ) +return -EINVAL ;
While the RFC probably only specifies masks up to /64, the general algorithm is sustainable up to at least /96.
Extending the RFC's section 3.6 ("/48 Prefix Mapping") example, fd01:0203:0405:0001:0000:0000:0000:1234/112 (specification per ip addr) would become 2001:0db8:0001:0000:0000:0000:d550:1234.
Not everybody runs exclusively on EUI64-SLAAC / PRIVACY addresses :)
net/ipv6/netfilter/ip6t_NPT.c line 125
Quoted 3 lines
net/ipv6/netfilter/ip6t_NPT.c new file +3
-0+static struct xt_target ip6t_npt_target_reg[]__read_mostly = { + { + .name ="SNPT" ,
IETF did quite a job again... NPT as an acronym is quite close to NAPT - too close.
Since it's essentially NETMAP, having something in that ballpark may seem more fitting. NPMAP? (Translation is mapping - henceforh "Network Prefix Mapping")
I would hint towards choosing a different name; the P in NPT may be (mis)understood as port (due to the common "NAPT") keyword.
net/ipv6/netfilter/ip6t_NPT.c line 132
Quoted 7 lines
net/ipv6/netfilter/ip6t_NPT.c new file +7
-0+ .target = ip6t_snpt_tg, + .targetsize = sizeof(struct ip6t_npt_tginfo), + .checkentry = ip6t_npt_checkentry, + .family = NFPROTO_IPV6, + .hooks = (1 <<NF_INET_LOCAL_IN ) | + (1 << NF_INET_POST_ROUTING), + .me = THIS_MODULE,
Should perhaps a .table = "mangle" be added?
Are any tricks on the userspace side needed to use SNPT/SNPMAP? Since I spot no code telling conntrack about the address mingling, one would have to use -j CT --notrack or the rawpost table, like it's done for RAWSNAT in xtables-addons, would he not?
Re: [PATCH 19/19] netfilter: ip6tables: add stateless IPv6-to-IPv6 Network Prefix Translation target
Quoted 11 lines · Jan Engelhardt
net/ipv6/netfilter/Kconfig config IP6_NF_TARGET_REDIRECT · line 185
Quoted 6 lines · On Thursday 2012-08-09 22:09, [email protected] wrote:
net/ipv6/netfilter/Kconfig +6
-0+config IP6_NF_TARGET_NPT + tristate "NPT (Network Prefix translation) target support" + depends on NETFILTER_ADVANCED + help + This option adda `SNPT' and `DNPT' target, which perform stateless + IPv6-to-IPv6 Network Prefix Translation (RFC 6296).Fixes/suggestion in the help text (near "adda" and subsequent).
Quoted 6 lines
config
IP6_NF_TARGET_NPT
tristate "NPT (Network Prefix translation) target support" depends onNETFILTER_ADVANCED
---help---
This option adds the "SNPT" and "DNPT" targets, which perform stateless IPv6-to-IPv6 Network Prefix Translation per RFC 6296.
Thanks, changes.
Quoted 8 lines
Quoted 7 lines
+/*
+ * Copyright (c) 2011, 2012 Patrick McHardy <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
Quoted 5 lines
GNU sometimes has a strange way of expressing their (C) lines, listing all years separately, as if "1989-1991,1994-1999,2001-2005" was not sufficient. In your case, would "2011-2012" work?
Any objection to adding a "(or later)" clause to the set?
Yeah this is a stupid habit that doesn't matter anyway, in all jurisdictions I care about copyright duration is based on the lifetime of the author. I'll try to find out whether just adding a copyright statement without any specific year would be fine for my purposes.
Quoted 12 lines
net/ipv6/netfilter/ip6t_NPT.c line 43
Quoted 8 lines
net/ipv6/netfilter/ip6t_NPT.c new file +8
-0+static int ip6t_npt_checkentry (const struct xt_tgchk_param *par) +{ +struct ip6t_npt_tginfo *npt = par->targinfo; +__sum16 src_sum =0 , dst_sum =0 ; +unsigned int i; + +if (npt->src_pfx_len >64 || npt->dst_pfx_len >64 ) +return -EINVAL ;While the RFC probably only specifies masks up to /64, the general algorithm is sustainable up to at least /96.
Quoted 5 lines
Extending the RFC's section 3.6 ("/48 Prefix Mapping") example, fd01:0203:0405:0001:0000:0000:0000:1234/112 (specification per
ip addr) would become 2001:0db8:0001:0000:0000:0000:d550:1234.Not everybody runs exclusively on EUI64-SLAAC / PRIVACY addresses :)
I'll think about it. If you want to send a patch, please go ahead ;)
Quoted 9 lines
net/ipv6/netfilter/ip6t_NPT.c line 125
Quoted 3 lines
net/ipv6/netfilter/ip6t_NPT.c new file +3
-0+static struct xt_target ip6t_npt_target_reg[]__read_mostly = { + { + .name ="SNPT" ,IETF did quite a job again... NPT as an acronym is quite close to NAPT - too close.
Since it's essentially NETMAP, having something in that ballpark may seem more fitting. NPMAP? (Translation is mapping - henceforh "Network Prefix Mapping")
So we'd have SNPMAP and DNPMAP. I like NPMAP, but SNPMAP and DNPMAP don't sound that much better, so I think I prefer keeping the currently used abrevation of Network Prefix Translation. I don't care much though.
Quoted 3 lines
I would hint towards choosing a different name; the P in NPT may be (mis)understood as port (due to the common "NAPT") keyword.
Well, I think people using computers are used to tons of similar sounding acronyms and abrevations. They'll manage ;)
Quoted 9 lines
net/ipv6/netfilter/ip6t_NPT.c line 132
Quoted 7 lines
net/ipv6/netfilter/ip6t_NPT.c new file +7
-0+ .target = ip6t_snpt_tg, + .targetsize = sizeof(struct ip6t_npt_tginfo), + .checkentry = ip6t_npt_checkentry, + .family = NFPROTO_IPV6, + .hooks = (1 <<NF_INET_LOCAL_IN ) | + (1 << NF_INET_POST_ROUTING), + .me = THIS_MODULE,Should perhaps a .table = "mangle" be added?
I've been proposing to lift the mangle restriction on all targets for years. Basically the only special thing about the mangle table is rerouting on mark changes. Everything else works just fine in other tables (with NAT being somewhat special as well), even marking packets if you don't need rerouting, its even more performant in that case since no extra routing lookups need to be done. So I don't see a reason to impose artificial limitations.
Quoted 4 lines
Are any tricks on the userspace side needed to use SNPT/SNPMAP? Since I spot no code telling conntrack about the address mingling, one would have to use -j CT --notrack or the rawpost table, like it's done for RAWSNAT in xtables-addons, would he not?
Yes, if connection tracking is used (which is not necessary of course) its best to exclude the translated packets from tracking. There's actually a lot of potential for improvement here. One thing is telling connection tracking, if its used, about the translations, so it can properly track packets. Another thing is, with stateless translation you still need ALGs to take care of addresses in layer 7 protocols. I've been thinking about how to make the existing NAT helpers work without conntrack and NAT, but its not easy and requires a lot of restructuring of the existing code. Its something we can still add later, its something that just affects the kernel.
Quoted 7 lines · [email protected] writes:
The following patches contain an updated version of IPv6 NAT against Linus' current tree.
The series is organized as follows:
- Patches 01-03 contain bugfixes for SIP helper bugs/regressions present in the current kernel
Why not just delete this code? The current best practices are to disable ALGs for SIP. To the point in some circles people recommend running SIP over TLS to avoid over helpful NAT ALGs.
Eric
Quoted 5 lines · Eric W. Biederman
Quoted 3 lines · [email protected] writes:
The following patches contain an updated version of IPv6 NAT against Linus' current tree.
Quoted 8 lines
Quoted 4 lines
The series is organized as follows:
- Patches 01-03 contain bugfixes for SIP helper bugs/regressions present in the current kernel
Why not just delete this code? The current best practices are to disable ALGs for SIP. To the point in some circles people recommend running SIP over TLS to avoid over helpful NAT ALGs.
And where can I read up on these best practices and how well they work?
In any case, these patches are all for the connection tracking helper,
which is needed unless you want to open up your firewall for every possible RTP source, in which case you can simply disable it. Some people are also using it to proritize RTP streams without any filtering.
Also, even if the NAT helper would not mangle packets, it is still needed to adjust expectations. so incoming connections can go to the correct destination. That is, direct RTP connections between two endpoints
that didn't have any direct signalling communication before
You can of course also proxy everything through your SIP provider (including internal calls) and/or use STUN (which is unreliable under Linux). I prefer not to.
Pablo Neira Ayuso
maintainerHi Patrick,
Quoted 7 lines · On Thu, Aug 09, 2012 at 10:08:44PM +0200, [email protected] wrote:
The following patches contain an updated version of IPv6 NAT against Linus' current tree.
The series is organized as follows:
- Patches 01-03 contain bugfixes for SIP helper bugs/regressions present in the current kernel
Thanks, I'll pass these to David.
I have also two more to fixes to oopses regarding SIP. I'm expecting one user to finally confirm that their issues are fixed.
Quoted 25 lines
- Patches 04-06 improve conntrack fragmentation handling, the IPv6 parts are also a precondition for IPv6 NAT
- Patches 07 and 08 prepare the current NAT code for conversion to an address family independant core, but contain no functional changes
- Patch 09 adds the address family independant NAT core and converts the existing IPv4-only NAT code to an AF-specific module
- Patches 10 and 11 add some infrastructure for IPv6 NAT
- Patch 12 adds IPv6 NAT support
- Patches 13-15 add IPv6 specific NAT targets
- Patches 16-19 add some IPv6-capable ports of existing NAT helpers
- Patch 19 is independant of the IPv6 NAT code and adds support for stateless IPv6 prefix translation, just to relieve my conscience ;)
Since the last posting numerous bugs have been fixed, I don't remember all of them, the more important ones include:
Quoted 7 lines
- automatic NAT module loading in ctnetlink
- address selection when mapping to IPv6 ranges
- handling of IPv6 fragments
- NAT handling of ICMPv6 error messages
Thanks, I was keeping the previous patchset in one branch:
http://1984.lsi.us.es/git/nf-next/log/?h=nf-nat4
You can also find forward ports of netlink-mmap (from Florian Westpal) and one for nftables from myself in that tree.
Quoted 2 lines
Besides implementing IPv6 NAT, there are no known bugs left. Userspace patches will follow shortly.
We have this branch for iptables IPv6 NAT:
http://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=shortlog;h=refs/heads/nf-nat
Let me know if you're OK with these.
Quoted 8 lines · Pablo Neira Ayuso
Hi Patrick,
Quoted 5 lines · On Thu, Aug 09, 2012 at 10:08:44PM +0200, [email protected] wrote:
The following patches contain an updated version of IPv6 NAT against Linus' current tree.
The series is organized as follows:
Quoted 7 lines
Quoted 2 lines
- Patches 01-03 contain bugfixes for SIP helper bugs/regressions present in the current kernel
Thanks, I'll pass these to David.
I have also two more to fixes to oopses regarding SIP. I'm expecting one user to finally confirm that their issues are fixed.
If you want me to have a look as well, just send me an URL or the patches.
Quoted 31 lines
Quoted 31 lines
- Patches 04-06 improve conntrack fragmentation handling, the IPv6 parts are also a precondition for IPv6 NAT
- Patches 07 and 08 prepare the current NAT code for conversion to an address family independant core, but contain no functional changes
- Patch 09 adds the address family independant NAT core and converts the existing IPv4-only NAT code to an AF-specific module
- Patches 10 and 11 add some infrastructure for IPv6 NAT
- Patch 12 adds IPv6 NAT support
- Patches 13-15 add IPv6 specific NAT targets
- Patches 16-19 add some IPv6-capable ports of existing NAT helpers
- Patch 19 is independant of the IPv6 NAT code and adds support for stateless IPv6 prefix translation, just to relieve my conscience ;)
Since the last posting numerous bugs have been fixed, I don't remember all of them, the more important ones include:
- automatic NAT module loading in ctnetlink
- address selection when mapping to IPv6 ranges
- handling of IPv6 fragments
Quoted 8 lines
Quoted 1 line
- NAT handling of ICMPv6 error messages
Thanks, I was keeping the previous patchset in one branch:
http://1984.lsi.us.es/git/nf-next/log/?h=nf-nat4
You can also find forward ports of netlink-mmap (from Florian Westpal) and one for nftables from myself in that tree.
Thanks, Florian just pointed me to these trees. Will have a look at the changes compared to my tree. I'm actually intending to finish up the mmaped netlink work once I'm done with IPv6 NAT.
Quoted 8 lines
Quoted 2 lines
Besides implementing IPv6 NAT, there are no known bugs left. Userspace patches will follow shortly.
We have this branch for iptables IPv6 NAT:
http://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=shortlog;h=refs/heads/nf-nat
Let me know if you're OK with these.
For now I'll just accumulate feedback and will incorporate it into my tree. I'll also diff them against your tree and will then send the final result once all feedback/fixes are included.
Pablo Neira Ayuso
maintainerOn Thu, Aug 09, 2012 at 10:08:44PM +0200, [email protected] wrote:
[...]
Quoted 1 line
- Patches 16-19 add some IPv6-capable ports of existing NAT helpers
There was one for IRC also, did it get lost?
I also made TFTP, it was more or less trivial, you can find it here:
http://1984.lsi.us.es/git/nf-next/commit/?h=nf-nat4&id=ac2a06ab790386c8c8333dbf84584fc3f80fcdc5
Quoted 9 lines · Pablo Neira Ayuso
On Thu, Aug 09, 2012 at 10:08:44PM +0200, [email protected] wrote:
[...]Quoted 1 line
- Patches 16-19 add some IPv6-capable ports of existing NAT helpers
There was one for IRC also, did it get lost?
I also made TFTP, it was more or less trivial, you can find it here:
http://1984.lsi.us.es/git/nf-next/commit/?h=nf-nat4&id=ac2a06ab790386c8c8333dbf84584fc3f80fcdc5
I've already added your IRC and TFTP patches to my tree. Will send the latest version later today.
Quoted 2 lines · On 09. aug. 2012 22:08, [email protected] wrote:
The following patches contain an updated version of IPv6 NAT against Linus' current tree.
Hmmm. Looking in my crystal ball (hi #ipv6!), I predict that if this lands in mainline - and thus in consumer CPE/routers eventually - many ISP's will have little incentive to actually implement assigning of blocks to their consumer users like they "have to" today.
We have this wonderful chance of fixing a major problem with todays internet, but now we are going down this very slippery slope.
I do need this code for a experimental project myself, and acknowledge there may be some valid use cases, but I do not like the global implications one bit.
At least some big fat warnings please?
:-(
Quoted 9 lines · Andre Tomt
Quoted 2 lines · On 09. aug. 2012 22:08, [email protected] wrote:
The following patches contain an updated version of IPv6 NAT against Linus' current tree.
Hmmm. Looking in my crystal ball (hi #ipv6!), I predict that if this lands in mainline - and thus in consumer CPE/routers eventually - many ISP's will have little incentive to actually implement assigning of blocks to their consumer users like they "have to" today.
Quoted 8 lines
We have this wonderful chance of fixing a major problem with todays internet, but now we are going down this very slippery slope.
I do need this code for a experimental project myself, and acknowledge there may be some valid use cases, but I do not like the global implications one bit.
At least some big fat warnings please?
Clarification: This is about the NAT66 port-based 1:n NAT targets.
Quoted 13 lines · Andre Tomt
Quoted 12 lines · Andre Tomt
Quoted 2 lines · On 09. aug. 2012 22:08, [email protected] wrote:
The following patches contain an updated version of IPv6 NAT against Linus' current tree.
Hmmm. Looking in my crystal ball (hi #ipv6!), I predict that if this lands in mainline - and thus in consumer CPE/routers eventually - many ISP's will have little incentive to actually implement assigning of blocks to their consumer users like they "have to" today.
We have this wonderful chance of fixing a major problem with todays internet, but now we are going down this very slippery slope.
Quoted 7 lines
Quoted 5 lines
I do need this code for a experimental project myself, and acknowledge there may be some valid use cases, but I do not like the global implications one bit.
At least some big fat warnings please?
Clarification: This is about the NAT66 port-based 1:n NAT targets.
We can certainly add a warning to the Kconfig text or (better) the iptables manpage. But only a very small percentage of people who might end up (unknowingly) using this will ever see them.
Feel free to send a patch though.
Quoted 8 lines · Andre Tomt
Quoted 2 lines · On 09. aug. 2012 22:08, [email protected] wrote:
The following patches contain an updated version of IPv6 NAT against Linus' current tree.
Hmmm. Looking in my crystal ball (hi #ipv6!), I predict that if this lands in mainline - and thus in consumer CPE/routers eventually - many ISP's will have little incentive to actually implement assigning of blocks to their consumer users like they "have to" today.
I think the brokenness of IPv6 ND is still sufficient incentive to provide the customer with a prefix. Whether this prefix is constant over an extended period of time is a separate question. Even among consumers, preferences vary widely.
Signature · 1 line
Florian Weimer / Red Hat Product Security Team