Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cad8e944 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

parents 8ca2bdc7 9f0ede52
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -146,7 +146,7 @@ extern void nfnl_unlock(void);
extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);


extern int nfattr_parse(struct nfattr *tb[], int maxattr, 
extern void nfattr_parse(struct nfattr *tb[], int maxattr, 
			struct nfattr *nfa, int len);
			struct nfattr *nfa, int len);


#define nfattr_parse_nested(tb, max, nfa) \
#define nfattr_parse_nested(tb, max, nfa) \
+37 −46
Original line number Original line Diff line number Diff line
@@ -28,11 +28,8 @@
#include <linux/netlink.h>
#include <linux/netlink.h>
#include <linux/spinlock.h>
#include <linux/spinlock.h>
#include <linux/notifier.h>
#include <linux/notifier.h>
#include <linux/rtnetlink.h>


#include <linux/netfilter.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack.h>
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/ip_conntrack_core.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
@@ -58,14 +55,17 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb,
			    const struct ip_conntrack_tuple *tuple)
			    const struct ip_conntrack_tuple *tuple)
{
{
	struct ip_conntrack_protocol *proto;
	struct ip_conntrack_protocol *proto;
	int ret = 0;


	NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
	NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);


	proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
	proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
	if (proto && proto->tuple_to_nfattr)
	if (likely(proto && proto->tuple_to_nfattr)) {
		return proto->tuple_to_nfattr(skb, tuple);
		ret = proto->tuple_to_nfattr(skb, tuple);
		ip_conntrack_proto_put(proto);
	}


	return 0;
	return ret;


nfattr_failure:
nfattr_failure:
	return -1;
	return -1;
@@ -175,7 +175,7 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
{
{
	enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
	enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
	struct nfattr *nest_count = NFA_NEST(skb, type);
	struct nfattr *nest_count = NFA_NEST(skb, type);
	u_int64_t tmp;
	u_int32_t tmp;


	tmp = htonl(ct->counters[dir].packets);
	tmp = htonl(ct->counters[dir].packets);
	NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
	NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
@@ -479,9 +479,7 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)


	DEBUGP("entered %s\n", __FUNCTION__);
	DEBUGP("entered %s\n", __FUNCTION__);


	
	nfattr_parse_nested(tb, CTA_IP_MAX, attr);
	if (nfattr_parse_nested(tb, CTA_IP_MAX, attr) < 0)
		goto nfattr_failure;


	if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
	if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
		return -EINVAL;
		return -EINVAL;
@@ -497,9 +495,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
	DEBUGP("leaving\n");
	DEBUGP("leaving\n");


	return 0;
	return 0;

nfattr_failure:
	return -1;
}
}


static const int cta_min_proto[CTA_PROTO_MAX] = {
static const int cta_min_proto[CTA_PROTO_MAX] = {
@@ -521,8 +516,7 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,


	DEBUGP("entered %s\n", __FUNCTION__);
	DEBUGP("entered %s\n", __FUNCTION__);


	if (nfattr_parse_nested(tb, CTA_PROTO_MAX, attr) < 0)
	nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
		goto nfattr_failure;


	if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
	if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
		return -EINVAL;
		return -EINVAL;
@@ -539,9 +533,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
	}
	}
	
	
	return ret;
	return ret;

nfattr_failure:
	return -1;
}
}


static inline int
static inline int
@@ -555,8 +546,7 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,


	memset(tuple, 0, sizeof(*tuple));
	memset(tuple, 0, sizeof(*tuple));


	if (nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]) < 0)
	nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
		goto nfattr_failure;


	if (!tb[CTA_TUPLE_IP-1])
	if (!tb[CTA_TUPLE_IP-1])
		return -EINVAL;
		return -EINVAL;
@@ -583,9 +573,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
	DEBUGP("leaving\n");
	DEBUGP("leaving\n");


	return 0;
	return 0;

nfattr_failure:
	return -1;
}
}


#ifdef CONFIG_IP_NF_NAT_NEEDED
#ifdef CONFIG_IP_NF_NAT_NEEDED
@@ -603,11 +590,10 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,


	DEBUGP("entered %s\n", __FUNCTION__);
	DEBUGP("entered %s\n", __FUNCTION__);


	if (nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr) < 0)
	nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
		goto nfattr_failure;


	if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
	if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
		goto nfattr_failure;
		return -EINVAL;


	npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
	npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
	if (!npt)
	if (!npt)
@@ -626,9 +612,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,


	DEBUGP("leaving\n");
	DEBUGP("leaving\n");
	return 0;
	return 0;

nfattr_failure:
	return -1;
}
}


static inline int
static inline int
@@ -642,8 +625,7 @@ ctnetlink_parse_nat(struct nfattr *cda[],


	memset(range, 0, sizeof(*range));
	memset(range, 0, sizeof(*range));
	
	
	if (nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]) < 0)
	nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
		goto nfattr_failure;


	if (tb[CTA_NAT_MINIP-1])
	if (tb[CTA_NAT_MINIP-1])
		range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
		range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
@@ -665,9 +647,6 @@ ctnetlink_parse_nat(struct nfattr *cda[],


	DEBUGP("leaving\n");
	DEBUGP("leaving\n");
	return 0;
	return 0;

nfattr_failure:
	return -1;
}
}
#endif
#endif


@@ -678,8 +657,7 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)


	DEBUGP("entered %s\n", __FUNCTION__);
	DEBUGP("entered %s\n", __FUNCTION__);


	if (nfattr_parse_nested(tb, CTA_HELP_MAX, attr) < 0)
	nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
		goto nfattr_failure;


	if (!tb[CTA_HELP_NAME-1])
	if (!tb[CTA_HELP_NAME-1])
		return -EINVAL;
		return -EINVAL;
@@ -687,9 +665,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
	*helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]);
	*helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]);


	return 0;
	return 0;

nfattr_failure:
	return -1;
}
}


static int
static int
@@ -804,7 +779,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
	ct = tuplehash_to_ctrack(h);
	ct = tuplehash_to_ctrack(h);


	err = -ENOMEM;
	err = -ENOMEM;
	skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
	skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!skb2) {
	if (!skb2) {
		ip_conntrack_put(ct);
		ip_conntrack_put(ct);
		return -ENOMEM;
		return -ENOMEM;
@@ -827,7 +802,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
free:
free:
	kfree_skb(skb2);
	kfree_skb(skb2);
out:
out:
	return -1;
	return err;
}
}


static inline int
static inline int
@@ -957,8 +932,7 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
	u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
	u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
	int err = 0;
	int err = 0;


	if (nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr) < 0)
	nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
		goto nfattr_failure;


	proto = ip_conntrack_proto_find_get(npt);
	proto = ip_conntrack_proto_find_get(npt);
	if (!proto)
	if (!proto)
@@ -969,9 +943,6 @@ ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
	ip_conntrack_proto_put(proto); 
	ip_conntrack_proto_put(proto); 


	return err;
	return err;

nfattr_failure:
	return -ENOMEM;
}
}


static int
static int
@@ -1005,6 +976,11 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
			return err;
			return err;
	}
	}


#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
	if (cda[CTA_MARK-1])
		ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
#endif

	DEBUGP("all done\n");
	DEBUGP("all done\n");
	return 0;
	return 0;
}
}
@@ -1048,6 +1024,11 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
	if (ct->helper)
	if (ct->helper)
		ip_conntrack_helper_put(ct->helper);
		ip_conntrack_helper_put(ct->helper);


#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
	if (cda[CTA_MARK-1])
		ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
#endif

	DEBUGP("conntrack with id %u inserted\n", ct->id);
	DEBUGP("conntrack with id %u inserted\n", ct->id);
	return 0;
	return 0;


@@ -1312,6 +1293,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
	if (!exp)
	if (!exp)
		return -ENOENT;
		return -ENOENT;


	if (cda[CTA_EXPECT_ID-1]) {
		u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
		if (exp->id != ntohl(id)) {
			ip_conntrack_expect_put(exp);
			return -ENOENT;
		}
	}	

	err = -ENOMEM;
	err = -ENOMEM;
	skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
	skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!skb2)
	if (!skb2)
@@ -1554,6 +1543,8 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
	.cb				= ctnl_exp_cb,
	.cb				= ctnl_exp_cb,
};
};


MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);

static int __init ctnetlink_init(void)
static int __init ctnetlink_init(void)
{
{
	int ret;
	int ret;
+8 −7
Original line number Original line Diff line number Diff line
@@ -151,13 +151,13 @@ icmp_error_message(struct sk_buff *skb,
	/* Not enough header? */
	/* Not enough header? */
	inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
	inside = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_in), &_in);
	if (inside == NULL)
	if (inside == NULL)
		return NF_ACCEPT;
		return -NF_ACCEPT;


	/* Ignore ICMP's containing fragments (shouldn't happen) */
	/* Ignore ICMP's containing fragments (shouldn't happen) */
	if (inside->ip.frag_off & htons(IP_OFFSET)) {
	if (inside->ip.frag_off & htons(IP_OFFSET)) {
		DEBUGP("icmp_error_track: fragment of proto %u\n",
		DEBUGP("icmp_error_track: fragment of proto %u\n",
		       inside->ip.protocol);
		       inside->ip.protocol);
		return NF_ACCEPT;
		return -NF_ACCEPT;
	}
	}


	innerproto = ip_conntrack_proto_find_get(inside->ip.protocol);
	innerproto = ip_conntrack_proto_find_get(inside->ip.protocol);
@@ -166,7 +166,7 @@ icmp_error_message(struct sk_buff *skb,
	if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
	if (!ip_ct_get_tuple(&inside->ip, skb, dataoff, &origtuple, innerproto)) {
		DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
		DEBUGP("icmp_error: ! get_tuple p=%u", inside->ip.protocol);
		ip_conntrack_proto_put(innerproto);
		ip_conntrack_proto_put(innerproto);
		return NF_ACCEPT;
		return -NF_ACCEPT;
	}
	}


	/* Ordinarily, we'd expect the inverted tupleproto, but it's
	/* Ordinarily, we'd expect the inverted tupleproto, but it's
@@ -174,7 +174,7 @@ icmp_error_message(struct sk_buff *skb,
	if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
	if (!ip_ct_invert_tuple(&innertuple, &origtuple, innerproto)) {
		DEBUGP("icmp_error_track: Can't invert tuple\n");
		DEBUGP("icmp_error_track: Can't invert tuple\n");
		ip_conntrack_proto_put(innerproto);
		ip_conntrack_proto_put(innerproto);
		return NF_ACCEPT;
		return -NF_ACCEPT;
	}
	}
	ip_conntrack_proto_put(innerproto);
	ip_conntrack_proto_put(innerproto);


@@ -190,7 +190,7 @@ icmp_error_message(struct sk_buff *skb,


		if (!h) {
		if (!h) {
			DEBUGP("icmp_error_track: no match\n");
			DEBUGP("icmp_error_track: no match\n");
			return NF_ACCEPT;
			return -NF_ACCEPT;
		}
		}
		/* Reverse direction from that found */
		/* Reverse direction from that found */
		if (DIRECTION(h) != IP_CT_DIR_REPLY)
		if (DIRECTION(h) != IP_CT_DIR_REPLY)
@@ -296,7 +296,8 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
				struct ip_conntrack_tuple *tuple)
				struct ip_conntrack_tuple *tuple)
{
{
	if (!tb[CTA_PROTO_ICMP_TYPE-1]
	if (!tb[CTA_PROTO_ICMP_TYPE-1]
	    || !tb[CTA_PROTO_ICMP_CODE-1])
	    || !tb[CTA_PROTO_ICMP_CODE-1]
	    || !tb[CTA_PROTO_ICMP_ID-1])
		return -1;
		return -1;


	tuple->dst.u.icmp.type = 
	tuple->dst.u.icmp.type = 
@@ -304,7 +305,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
	tuple->dst.u.icmp.code =
	tuple->dst.u.icmp.code =
			*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
			*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
	tuple->src.u.icmp.id =
	tuple->src.u.icmp.id =
			*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
			*(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);


	return 0;
	return 0;
}
}
+6 −5
Original line number Original line Diff line number Diff line
@@ -362,8 +362,12 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
	struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
	struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
	struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
	struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];


        if (nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr) < 0)
	/* updates could not contain anything about the private
                goto nfattr_failure;
	 * protocol info, in that case skip the parsing */
	if (!attr)
		return 0;

        nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);


	if (!tb[CTA_PROTOINFO_TCP_STATE-1])
	if (!tb[CTA_PROTOINFO_TCP_STATE-1])
		return -EINVAL;
		return -EINVAL;
@@ -374,9 +378,6 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
	write_unlock_bh(&tcp_lock);
	write_unlock_bh(&tcp_lock);


	return 0;
	return 0;

nfattr_failure:
	return -1;
}
}
#endif
#endif


+26 −2
Original line number Original line Diff line number Diff line
@@ -73,6 +73,7 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
	struct ip_conntrack_tuple t;
	struct ip_conntrack_tuple t;
	struct ip_ct_pptp_master *ct_pptp_info;
	struct ip_ct_pptp_master *ct_pptp_info;
	struct ip_nat_pptp *nat_pptp_info;
	struct ip_nat_pptp *nat_pptp_info;
	struct ip_nat_range range;


	ct_pptp_info = &master->help.ct_pptp_info;
	ct_pptp_info = &master->help.ct_pptp_info;
	nat_pptp_info = &master->nat.help.nat_pptp_info;
	nat_pptp_info = &master->nat.help.nat_pptp_info;
@@ -110,7 +111,30 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
		DEBUGP("not found!\n");
		DEBUGP("not found!\n");
	}
	}


	ip_nat_follow_master(ct, exp);
	/* This must be a fresh one. */
	BUG_ON(ct->status & IPS_NAT_DONE_MASK);

	/* Change src to where master sends to */
	range.flags = IP_NAT_RANGE_MAP_IPS;
	range.min_ip = range.max_ip
		= ct->master->tuplehash[!exp->dir].tuple.dst.ip;
	if (exp->dir == IP_CT_DIR_ORIGINAL) {
		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
		range.min = range.max = exp->saved_proto;
	}
	/* hook doesn't matter, but it has to do source manip */
	ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);

	/* For DST manip, map port here to where it's expected. */
	range.flags = IP_NAT_RANGE_MAP_IPS;
	range.min_ip = range.max_ip
		= ct->master->tuplehash[!exp->dir].tuple.src.ip;
	if (exp->dir == IP_CT_DIR_REPLY) {
		range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
		range.min = range.max = exp->saved_proto;
	}
	/* hook doesn't matter, but it has to do destination manip */
	ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
}
}


/* outbound packets == from PNS to PAC */
/* outbound packets == from PNS to PAC */
@@ -213,7 +237,7 @@ pptp_exp_gre(struct ip_conntrack_expect *expect_orig,


	/* alter expectation for PNS->PAC direction */
	/* alter expectation for PNS->PAC direction */
	invert_tuplepr(&inv_t, &expect_orig->tuple);
	invert_tuplepr(&inv_t, &expect_orig->tuple);
	expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id);
	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.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);
	expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
	expect_orig->dir = IP_CT_DIR_ORIGINAL;
	expect_orig->dir = IP_CT_DIR_ORIGINAL;
Loading