Skip to content

Commit

Permalink
[NETFILTER]: PPTP conntrack: simplify expectation handling
Browse files Browse the repository at this point in the history
Remove duplicated expectation handling in the NAT helper and simplify
the remains in the conntrack helper.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Sep 22, 2006
1 parent 857c06d commit cf9f815
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 117 deletions.
2 changes: 1 addition & 1 deletion include/linux/netfilter_ipv4/ip_conntrack_pptp.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ extern int
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq);

extern int
extern void
(*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *exp_orig,
struct ip_conntrack_expect *exp_reply);

Expand Down
92 changes: 31 additions & 61 deletions net/ipv4/netfilter/ip_conntrack_helper_pptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ int
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq);

int
void
(*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *expect_orig,
struct ip_conntrack_expect *expect_reply);

Expand Down Expand Up @@ -219,93 +219,63 @@ static void pptp_destroy_siblings(struct ip_conntrack *ct)

/* expect GRE connections (PNS->PAC and PAC->PNS direction) */
static inline int
exp_gre(struct ip_conntrack *master,
exp_gre(struct ip_conntrack *ct,
__be16 callid,
__be16 peer_callid)
{
struct ip_conntrack_tuple inv_tuple;
struct ip_conntrack_tuple exp_tuples[] = {
/* tuple in original direction, PNS->PAC */
{ .src = { .ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip,
.u = { .gre = { .key = peer_callid } }
},
.dst = { .ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip,
.u = { .gre = { .key = callid } },
.protonum = IPPROTO_GRE
},
},
/* tuple in reply direction, PAC->PNS */
{ .src = { .ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip,
.u = { .gre = { .key = callid } }
},
.dst = { .ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip,
.u = { .gre = { .key = peer_callid } },
.protonum = IPPROTO_GRE
},
}
};
struct ip_conntrack_expect *exp_orig, *exp_reply;
int ret = 1;

exp_orig = ip_conntrack_expect_alloc(master);
exp_orig = ip_conntrack_expect_alloc(ct);
if (exp_orig == NULL)
goto out;

exp_reply = ip_conntrack_expect_alloc(master);
exp_reply = ip_conntrack_expect_alloc(ct);
if (exp_reply == NULL)
goto out_put_orig;

memcpy(&exp_orig->tuple, &exp_tuples[0], sizeof(exp_orig->tuple));
/* original direction, PNS->PAC */
exp_orig->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
exp_orig->tuple.src.u.gre.key = peer_callid;
exp_orig->tuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
exp_orig->tuple.dst.u.gre.key = callid;
exp_orig->tuple.dst.protonum = IPPROTO_GRE;

exp_orig->mask.src.ip = 0xffffffff;
exp_orig->mask.src.u.all = 0;
exp_orig->mask.dst.u.all = 0;
exp_orig->mask.dst.u.gre.key = htons(0xffff);
exp_orig->mask.dst.ip = 0xffffffff;
exp_orig->mask.dst.protonum = 0xff;

exp_orig->master = master;
exp_orig->master = ct;
exp_orig->expectfn = pptp_expectfn;
exp_orig->flags = 0;

/* both expectations are identical apart from tuple */
memcpy(exp_reply, exp_orig, sizeof(*exp_reply));
memcpy(&exp_reply->tuple, &exp_tuples[1], sizeof(exp_reply->tuple));

if (ip_nat_pptp_hook_exp_gre)
ret = ip_nat_pptp_hook_exp_gre(exp_orig, exp_reply);
else {

DEBUGP("calling expect_related PNS->PAC");
DUMP_TUPLE(&exp_orig->tuple);
/* reply direction, PAC->PNS */
exp_reply->tuple.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
exp_reply->tuple.src.u.gre.key = callid;
exp_reply->tuple.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
exp_reply->tuple.dst.u.gre.key = peer_callid;
exp_reply->tuple.dst.protonum = IPPROTO_GRE;

if (ip_conntrack_expect_related(exp_orig) != 0) {
DEBUGP("cannot expect_related()\n");
goto out_put_both;
}

DEBUGP("calling expect_related PAC->PNS");
DUMP_TUPLE(&exp_reply->tuple);

if (ip_conntrack_expect_related(exp_reply) != 0) {
DEBUGP("cannot expect_related()\n");
goto out_unexpect_orig;
}

/* Add GRE keymap entries */
if (ip_ct_gre_keymap_add(master, &exp_reply->tuple, 0) != 0) {
DEBUGP("cannot keymap_add() exp\n");
goto out_unexpect_both;
}

invert_tuplepr(&inv_tuple, &exp_reply->tuple);
if (ip_ct_gre_keymap_add(master, &inv_tuple, 1) != 0) {
ip_ct_gre_keymap_destroy(master);
DEBUGP("cannot keymap_add() exp_inv\n");
goto out_unexpect_both;
}
ret = 0;
if (ip_nat_pptp_hook_exp_gre)
ip_nat_pptp_hook_exp_gre(exp_orig, exp_reply);
if (ip_conntrack_expect_related(exp_orig) != 0)
goto out_put_both;
if (ip_conntrack_expect_related(exp_reply) != 0)
goto out_unexpect_orig;

/* Add GRE keymap entries */
if (ip_ct_gre_keymap_add(ct, &exp_orig->tuple, 0) != 0)
goto out_unexpect_both;
if (ip_ct_gre_keymap_add(ct, &exp_reply->tuple, 1) != 0) {
ip_ct_gre_keymap_destroy(ct);
goto out_unexpect_both;
}
ret = 0;

out_put_both:
ip_conntrack_expect_put(exp_reply);
Expand Down
58 changes: 3 additions & 55 deletions net/ipv4/netfilter/ip_nat_helper_pptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,80 +211,28 @@ pptp_outbound_pkt(struct sk_buff **pskb,
return NF_ACCEPT;
}

static int
static void
pptp_exp_gre(struct ip_conntrack_expect *expect_orig,
struct ip_conntrack_expect *expect_reply)
{
struct ip_ct_pptp_master *ct_pptp_info =
&expect_orig->master->help.ct_pptp_info;
struct ip_nat_pptp *nat_pptp_info =
&expect_orig->master->nat.help.nat_pptp_info;

struct ip_conntrack *ct = expect_orig->master;

struct ip_conntrack_tuple inv_t;
struct ip_conntrack_tuple *orig_t, *reply_t;
struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;
struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;

/* save original PAC call ID in nat_info */
nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id;

/* alter expectation */
orig_t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
reply_t = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;

/* alter expectation for PNS->PAC direction */
invert_tuplepr(&inv_t, &expect_orig->tuple);
expect_orig->saved_proto.gre.key = ct_pptp_info->pns_call_id;
expect_orig->tuple.src.u.gre.key = nat_pptp_info->pns_call_id;
expect_orig->tuple.dst.u.gre.key = ct_pptp_info->pac_call_id;
expect_orig->dir = IP_CT_DIR_ORIGINAL;
inv_t.src.ip = reply_t->src.ip;
inv_t.dst.ip = reply_t->dst.ip;
inv_t.src.u.gre.key = nat_pptp_info->pac_call_id;
inv_t.dst.u.gre.key = ct_pptp_info->pns_call_id;

if (!ip_conntrack_expect_related(expect_orig)) {
DEBUGP("successfully registered expect\n");
} else {
DEBUGP("can't expect_related(expect_orig)\n");
return 1;
}

/* alter expectation for PAC->PNS direction */
invert_tuplepr(&inv_t, &expect_reply->tuple);
expect_reply->saved_proto.gre.key = nat_pptp_info->pns_call_id;
expect_reply->tuple.src.u.gre.key = nat_pptp_info->pac_call_id;
expect_reply->tuple.dst.u.gre.key = ct_pptp_info->pns_call_id;
expect_reply->dir = IP_CT_DIR_REPLY;
inv_t.src.ip = orig_t->src.ip;
inv_t.dst.ip = orig_t->dst.ip;
inv_t.src.u.gre.key = nat_pptp_info->pns_call_id;
inv_t.dst.u.gre.key = ct_pptp_info->pac_call_id;

if (!ip_conntrack_expect_related(expect_reply)) {
DEBUGP("successfully registered expect\n");
} else {
DEBUGP("can't expect_related(expect_reply)\n");
ip_conntrack_unexpect_related(expect_orig);
return 1;
}

if (ip_ct_gre_keymap_add(ct, &expect_reply->tuple, 0) < 0) {
DEBUGP("can't register original keymap\n");
ip_conntrack_unexpect_related(expect_orig);
ip_conntrack_unexpect_related(expect_reply);
return 1;
}

if (ip_ct_gre_keymap_add(ct, &inv_t, 1) < 0) {
DEBUGP("can't register reply keymap\n");
ip_conntrack_unexpect_related(expect_orig);
ip_conntrack_unexpect_related(expect_reply);
ip_ct_gre_keymap_destroy(ct);
return 1;
}

return 0;
}

/* inbound packets == from PAC to PNS */
Expand Down

0 comments on commit cf9f815

Please sign in to comment.