aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Boncompte <jorge@dti2.net>2007-05-03 06:34:42 -0400
committerDavid S. Miller <davem@davemloft.net>2007-05-03 06:34:42 -0400
commitc2a1910b06fed96db77bb358c18c52a1fcf2b7fe (patch)
treea3e8fc944ea2a0bed4a6e02b6b0fb42e21444354
parent327850070b019a96853c533c152688546201c286 (diff)
[NETFILTER]: nf_nat_proto_gre: do not modify/corrupt GREv0 packets through NAT
While porting some changes of the 2.6.21-rc7 pptp/proto_gre conntrack and nat modules to a 2.4.32 kernel I noticed that the gre_key function returns a wrong pointer to the GRE key of a version 0 packet thus corrupting the packet payload. The intended behaviour for GREv0 packets is to act like nf_conntrack_proto_generic/nf_nat_proto_unknown so I have ripped the offending functions (not used anymore) and modified the nf_nat_proto_gre modules to not touch version 0 (non PPTP) packets. Signed-off-by: Jorge Boncompte <jorge@dti2.net> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter/nf_conntrack_proto_gre.h18
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_gre.c20
2 files changed, 8 insertions, 30 deletions
diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h
index 4e6bbce04ff8..535e4219d2bb 100644
--- a/include/linux/netfilter/nf_conntrack_proto_gre.h
+++ b/include/linux/netfilter/nf_conntrack_proto_gre.h
@@ -87,24 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
87/* delete keymap entries */ 87/* delete keymap entries */
88void nf_ct_gre_keymap_destroy(struct nf_conn *ct); 88void nf_ct_gre_keymap_destroy(struct nf_conn *ct);
89 89
90/* get pointer to gre key, if present */
91static inline __be32 *gre_key(struct gre_hdr *greh)
92{
93 if (!greh->key)
94 return NULL;
95 if (greh->csum || greh->routing)
96 return (__be32 *)(greh+sizeof(*greh)+4);
97 return (__be32 *)(greh+sizeof(*greh));
98}
99
100/* get pointer ot gre csum, if present */
101static inline __sum16 *gre_csum(struct gre_hdr *greh)
102{
103 if (!greh->csum)
104 return NULL;
105 return (__sum16 *)(greh+sizeof(*greh));
106}
107
108extern void nf_ct_gre_keymap_flush(void); 90extern void nf_ct_gre_keymap_flush(void);
109extern void nf_nat_need_gre(void); 91extern void nf_nat_need_gre(void);
110 92
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
index e5a34c17d927..c3908bc5a709 100644
--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
@@ -72,6 +72,11 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
72 __be16 *keyptr; 72 __be16 *keyptr;
73 unsigned int min, i, range_size; 73 unsigned int min, i, range_size;
74 74
75 /* If there is no master conntrack we are not PPTP,
76 do not change tuples */
77 if (!conntrack->master)
78 return 0;
79
75 if (maniptype == IP_NAT_MANIP_SRC) 80 if (maniptype == IP_NAT_MANIP_SRC)
76 keyptr = &tuple->src.u.gre.key; 81 keyptr = &tuple->src.u.gre.key;
77 else 82 else
@@ -122,18 +127,9 @@ gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff,
122 if (maniptype != IP_NAT_MANIP_DST) 127 if (maniptype != IP_NAT_MANIP_DST)
123 return 1; 128 return 1;
124 switch (greh->version) { 129 switch (greh->version) {
125 case 0: 130 case GRE_VERSION_1701:
126 if (!greh->key) { 131 /* We do not currently NAT any GREv0 packets.
127 DEBUGP("can't nat GRE w/o key\n"); 132 * Try to behave like "nf_nat_proto_unknown" */
128 break;
129 }
130 if (greh->csum) {
131 /* FIXME: Never tested this code... */
132 nf_proto_csum_replace4(gre_csum(greh), *pskb,
133 *(gre_key(greh)),
134 tuple->dst.u.gre.key, 0);
135 }
136 *(gre_key(greh)) = tuple->dst.u.gre.key;
137 break; 133 break;
138 case GRE_VERSION_PPTP: 134 case GRE_VERSION_PPTP:
139 DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); 135 DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));