Ejemplo n.º 1
0
/* timeout GRE data connections */
static int pptp_timeout_related(struct ip_conntrack *ct)
{
	struct list_head *cur_item, *next;
	struct ip_conntrack_expect *exp;

	/* FIXME: do we have to lock something ? */
	for (cur_item = ct->sibling_list.next;
	    cur_item != &ct->sibling_list; cur_item = next) {
		next = cur_item->next;
		exp = list_entry(cur_item, struct ip_conntrack_expect,
				 expected_list);

		ip_ct_gre_keymap_destroy(exp);
		if (!exp->sibling) {
			ip_conntrack_unexpect_related(exp);
			continue;
		}

		DEBUGP("setting timeout of conntrack %p to 0\n",
			exp->sibling);
		exp->sibling->proto.gre.timeout = 0;
		exp->sibling->proto.gre.stream_timeout = 0;
		ip_ct_refresh(exp->sibling, 0);
	}

	return 0;
}
Ejemplo n.º 2
0
static int pptp_expectfn(struct ip_conntrack *ct)
{
	struct ip_conntrack *master;
	struct ip_conntrack_expect *exp;

	#ifdef CONFIG_IFX_ALG_QOS  // chandrav
	IFX_ALG_QOS_DBG("\nPPTP_ALG: Master conntracker ifx_alg_qos_mark is : %x \n",ct->ifx_alg_qos_mark );
	/*
	 * Mark the connection tracker with PPTP ALG Application Family type 
	 * (IFX_ALG_PROTO_DATA) and PPTP ALG Protocol Family type 
	 * (IFX_ALG_PROTO_DATA)	
	 */
	ct->ifx_alg_qos_mark = IFX_ALG_APP_PPTP | IFX_ALG_PROTO_DATA;
	IFX_ALG_QOS_DBG("\nPPTP ALG:Marked the Child conntracker with:%x \n",
					ct->ifx_alg_qos_mark );	
	#endif /* CONFIG_IFX_ALG_QOS */

	DEBUGP("increasing timeouts\n");
	/* increase timeout of GRE data channel conntrack entry */
	ct->proto.gre.timeout = PPTP_GRE_TIMEOUT;
	ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT;

	master = master_ct(ct);
	if (!master) {
		DEBUGP(" no master!!!\n");
		return 0;
	}

	exp = ct->master;
	if (!exp) {
		DEBUGP("no expectation!!\n");
		return 0;
	}

	DEBUGP("completing tuples with ct info\n");
	/* we can do this, since we're unconfirmed */
	if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == 
		htonl(master->help.ct_pptp_info.pac_call_id)) {	
		/* assume PNS->PAC */
		ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = 
			htonl(master->help.ct_pptp_info.pns_call_id);
		ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
			htonl(master->help.ct_pptp_info.pns_call_id);
	} else {
		/* assume PAC->PNS */
		ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
			htonl(master->help.ct_pptp_info.pac_call_id);
		ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
			htonl(master->help.ct_pptp_info.pac_call_id);
	}
	
	/* delete other expectation */
	if (exp->expected_list.next != &exp->expected_list) {
		struct ip_conntrack_expect *other_exp;
		struct list_head *cur_item, *next;

		for (cur_item = master->sibling_list.next;
		     cur_item != &master->sibling_list; cur_item = next) {
			next = cur_item->next;
			other_exp = list_entry(cur_item,
					       struct ip_conntrack_expect,
					       expected_list);
			/* remove only if occurred at same sequence number */
			if (other_exp != exp && other_exp->seq == exp->seq) {
				DEBUGP("unexpecting other direction\n");
				ip_ct_gre_keymap_destroy(other_exp);
				ip_conntrack_unexpect_related(other_exp);
			}
		}
	}

	return 0;
}
Ejemplo n.º 3
0
/* expect GRE connections (PNS->PAC and PAC->PNS direction) */
static inline int
exp_gre(struct ip_conntrack *master,
	u_int32_t seq,
	u_int16_t callid,
	u_int16_t peer_callid)
{
	struct ip_conntrack_expect exp;
	struct ip_conntrack_tuple inv_tuple;

	memset(&exp, 0, sizeof(exp));
	/* tuple in original direction, PNS->PAC */
	exp.tuple.src.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
	exp.tuple.src.u.gre.key = htonl(ntohs(peer_callid));
	exp.tuple.dst.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;
	exp.tuple.dst.u.gre.key = htonl(ntohs(callid));
	exp.tuple.dst.u.gre.protocol = __constant_htons(GRE_PROTOCOL_PPTP);
	exp.tuple.dst.u.gre.version = GRE_VERSION_PPTP;
	exp.tuple.dst.protonum = IPPROTO_GRE;

	exp.mask.src.ip = 0xffffffff;
	exp.mask.src.u.all = 0;
	exp.mask.dst.u.all = 0;
	exp.mask.dst.u.gre.key = 0xffffffff;
	exp.mask.dst.u.gre.version = 0xff;
	exp.mask.dst.u.gre.protocol = 0xffff;
	exp.mask.dst.ip = 0xffffffff;
	exp.mask.dst.protonum = 0xffff;
			
	exp.seq = seq;
	exp.expectfn = pptp_expectfn;

	exp.help.exp_pptp_info.pac_call_id = ntohs(callid);
	exp.help.exp_pptp_info.pns_call_id = ntohs(peer_callid);

	DEBUGP("calling expect_related ");
	DUMP_TUPLE_RAW(&exp.tuple);
	
	/* Add GRE keymap entries */
	if (ip_ct_gre_keymap_add(&exp, &exp.tuple, 0) != 0)
		return 1;

	invert_tuplepr(&inv_tuple, &exp.tuple);
	if (ip_ct_gre_keymap_add(&exp, &inv_tuple, 1) != 0) {
		ip_ct_gre_keymap_destroy(&exp);
		return 1;
	}
	
	if (ip_conntrack_expect_related(master, &exp) != 0) {
		ip_ct_gre_keymap_destroy(&exp);
		DEBUGP("cannot expect_related()\n");
		return 1;
	}

	/* tuple in reply direction, PAC->PNS */
	exp.tuple.src.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;
	exp.tuple.src.u.gre.key = htonl(ntohs(callid));
	exp.tuple.dst.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;
	exp.tuple.dst.u.gre.key = htonl(ntohs(peer_callid));

	DEBUGP("calling expect_related ");
	DUMP_TUPLE_RAW(&exp.tuple);
	
	/* Add GRE keymap entries */
	ip_ct_gre_keymap_add(&exp, &exp.tuple, 0);
	invert_tuplepr(&inv_tuple, &exp.tuple);
	ip_ct_gre_keymap_add(&exp, &inv_tuple, 1);
	/* FIXME: cannot handle error correctly, since we need to free
	 * the above keymap :( */
	
	if (ip_conntrack_expect_related(master, &exp) != 0) {
		/* free the second pair of keypmaps */
		ip_ct_gre_keymap_destroy(&exp);
		DEBUGP("cannot expect_related():\n");
		return 1;
	}

	return 0;
}
Ejemplo n.º 4
0
static int
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;

	/* 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 = htons(ct_pptp_info->pns_call_id);
	expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
	expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
	inv_t.src.ip = reply_t->src.ip;
	inv_t.dst.ip = reply_t->dst.ip;
	inv_t.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
	inv_t.dst.u.gre.key = htons(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");
		ip_conntrack_expect_free(expect_orig);
		return 1;
	}

	/* alter expectation for PAC->PNS direction */
	invert_tuplepr(&inv_t, &expect_reply->tuple);
	expect_reply->saved_proto.gre.key = htons(nat_pptp_info->pns_call_id);
	expect_reply->tuple.src.u.gre.key = htons(nat_pptp_info->pac_call_id);
	expect_reply->tuple.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);
	inv_t.src.ip = orig_t->src.ip;
	inv_t.dst.ip = orig_t->dst.ip;
	inv_t.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
	inv_t.dst.u.gre.key = htons(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);
		ip_conntrack_expect_free(expect_reply);
		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;
}
Ejemplo n.º 5
0
static int pptp_expectfn(struct ip_conntrack *ct)
{
	struct ip_conntrack *master;
	struct ip_conntrack_expect *exp;

	DEBUGP("increasing timeouts\n");
	/* increase timeout of GRE data channel conntrack entry */
	ct->proto.gre.timeout = PPTP_GRE_TIMEOUT;
	ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT;

	master = master_ct(ct);
	if (!master) {
		DEBUGP(" no master!!!\n");
		return 0;
	}

	exp = ct->master;
	if (!exp) {
		DEBUGP("no expectation!!\n");
		return 0;
	}

	DEBUGP("completing tuples with ct info\n");
	/* we can do this, since we're unconfirmed */
	if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == 
		htonl(master->help.ct_pptp_info.pac_call_id)) {	
		/* assume PNS->PAC */
		ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = 
			htonl(master->help.ct_pptp_info.pns_call_id);
		ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
			htonl(master->help.ct_pptp_info.pns_call_id);
	} else {
		/* assume PAC->PNS */
		ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key =
			htonl(master->help.ct_pptp_info.pac_call_id);
		ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key =
			htonl(master->help.ct_pptp_info.pac_call_id);
	}
	
	/* delete other expectation */
	if (exp->expected_list.next != &exp->expected_list) {
		struct ip_conntrack_expect *other_exp;
		struct list_head *cur_item, *next;

		for (cur_item = master->sibling_list.next;
		     cur_item != &master->sibling_list; cur_item = next) {
			next = cur_item->next;
			other_exp = list_entry(cur_item,
					       struct ip_conntrack_expect,
					       expected_list);
			/* remove only if occurred at same sequence number */
			if (other_exp != exp && other_exp->seq == exp->seq) {
				DEBUGP("unexpecting other direction\n");
				ip_ct_gre_keymap_destroy(other_exp);
				ip_conntrack_unexpect_related(other_exp);
			}
		}
	}

	return 0;
}