Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (26 commits) decnet: Fix compiler warning in dn_dev.c IPV6: Fix default gateway criteria wrt. HIGH/LOW preference radv option net/802/fc.c: Fix compilation warnings netns: correct mib stats in ip6_route_me_harder() netns: fix net_generic array leak rt2x00: fix regression introduced by "mac80211: free up 2 bytes in skb->cb" rtl8187: Add USB ID for Belkin F5D7050 with RTL8187B chip p54usb: Device ID updates mac80211: fixme for kernel-doc ath9k/mac80211: disallow fragmentation in ath9k, report to userspace libertas : Remove unused variable warning for "old_channel" from cmd.c mac80211: Fix scan RX processing oops orinoco: fix unsafe locking in spectrum_cs_suspend orinoco: fix unsafe locking in orinoco_cs_resume cfg80211: fix debugfs error handling mac80211: fix debugfs netdev rename iwlwifi: fix ct kill configuration for 5350 mac80211: fix HT information element parsing p54: Fix compilation problem on PPC mac80211: fix debugfs lockup ...
This commit is contained in:
@@ -38,9 +38,16 @@
|
||||
#include <net/netfilter/nf_conntrack_core.h>
|
||||
#include <net/netfilter/nf_conntrack_extend.h>
|
||||
#include <net/netfilter/nf_conntrack_acct.h>
|
||||
#include <net/netfilter/nf_nat.h>
|
||||
|
||||
#define NF_CONNTRACK_VERSION "0.5.0"
|
||||
|
||||
unsigned int
|
||||
(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
|
||||
enum nf_nat_manip_type manip,
|
||||
struct nlattr *attr) __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
|
||||
|
||||
DEFINE_SPINLOCK(nf_conntrack_lock);
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_lock);
|
||||
|
||||
|
||||
@@ -689,71 +689,6 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_NAT_NEEDED
|
||||
static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
|
||||
[CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
|
||||
[CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
|
||||
};
|
||||
|
||||
static int nfnetlink_parse_nat_proto(struct nlattr *attr,
|
||||
const struct nf_conn *ct,
|
||||
struct nf_nat_range *range)
|
||||
{
|
||||
struct nlattr *tb[CTA_PROTONAT_MAX+1];
|
||||
const struct nf_nat_protocol *npt;
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
|
||||
if (npt->nlattr_to_range)
|
||||
err = npt->nlattr_to_range(tb, range);
|
||||
nf_nat_proto_put(npt);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
|
||||
[CTA_NAT_MINIP] = { .type = NLA_U32 },
|
||||
[CTA_NAT_MAXIP] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static inline int
|
||||
nfnetlink_parse_nat(struct nlattr *nat,
|
||||
const struct nf_conn *ct, struct nf_nat_range *range)
|
||||
{
|
||||
struct nlattr *tb[CTA_NAT_MAX+1];
|
||||
int err;
|
||||
|
||||
memset(range, 0, sizeof(*range));
|
||||
|
||||
err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[CTA_NAT_MINIP])
|
||||
range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
|
||||
|
||||
if (!tb[CTA_NAT_MAXIP])
|
||||
range->max_ip = range->min_ip;
|
||||
else
|
||||
range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
|
||||
|
||||
if (range->min_ip)
|
||||
range->flags |= IP_NAT_RANGE_MAP_IPS;
|
||||
|
||||
if (!tb[CTA_NAT_PROTO])
|
||||
return 0;
|
||||
|
||||
err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
ctnetlink_parse_help(struct nlattr *attr, char **helper_name)
|
||||
{
|
||||
@@ -878,6 +813,34 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
ctnetlink_parse_nat_setup(struct nf_conn *ct,
|
||||
enum nf_nat_manip_type manip,
|
||||
struct nlattr *attr)
|
||||
{
|
||||
typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
|
||||
|
||||
parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
|
||||
if (!parse_nat_setup) {
|
||||
#ifdef CONFIG_KMOD
|
||||
rcu_read_unlock();
|
||||
nfnl_unlock();
|
||||
if (request_module("nf-nat-ipv4") < 0) {
|
||||
nfnl_lock();
|
||||
rcu_read_lock();
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
nfnl_lock();
|
||||
rcu_read_lock();
|
||||
if (nfnetlink_parse_nat_setup_hook)
|
||||
return -EAGAIN;
|
||||
#endif
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return parse_nat_setup(ct, manip, attr);
|
||||
}
|
||||
|
||||
static int
|
||||
ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
|
||||
{
|
||||
@@ -897,31 +860,6 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
|
||||
/* ASSURED bit can only be set */
|
||||
return -EBUSY;
|
||||
|
||||
if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
|
||||
#ifndef CONFIG_NF_NAT_NEEDED
|
||||
return -EOPNOTSUPP;
|
||||
#else
|
||||
struct nf_nat_range range;
|
||||
|
||||
if (cda[CTA_NAT_DST]) {
|
||||
if (nfnetlink_parse_nat(cda[CTA_NAT_DST], ct,
|
||||
&range) < 0)
|
||||
return -EINVAL;
|
||||
if (nf_nat_initialized(ct, IP_NAT_MANIP_DST))
|
||||
return -EEXIST;
|
||||
nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
|
||||
}
|
||||
if (cda[CTA_NAT_SRC]) {
|
||||
if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct,
|
||||
&range) < 0)
|
||||
return -EINVAL;
|
||||
if (nf_nat_initialized(ct, IP_NAT_MANIP_SRC))
|
||||
return -EEXIST;
|
||||
nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Be careful here, modifying NAT bits can screw up things,
|
||||
* so don't let users modify them directly if they don't pass
|
||||
* nf_nat_range. */
|
||||
@@ -929,6 +867,31 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
|
||||
{
|
||||
#ifdef CONFIG_NF_NAT_NEEDED
|
||||
int ret;
|
||||
|
||||
if (cda[CTA_NAT_DST]) {
|
||||
ret = ctnetlink_parse_nat_setup(ct,
|
||||
IP_NAT_MANIP_DST,
|
||||
cda[CTA_NAT_DST]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (cda[CTA_NAT_SRC]) {
|
||||
ret = ctnetlink_parse_nat_setup(ct,
|
||||
IP_NAT_MANIP_SRC,
|
||||
cda[CTA_NAT_SRC]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int
|
||||
ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
|
||||
@@ -1157,6 +1120,14 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
|
||||
}
|
||||
}
|
||||
|
||||
if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
|
||||
err = ctnetlink_change_nat(ct, cda);
|
||||
if (err < 0) {
|
||||
rcu_read_unlock();
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (cda[CTA_PROTOINFO]) {
|
||||
err = ctnetlink_change_protoinfo(ct, cda);
|
||||
if (err < 0) {
|
||||
|
||||
@@ -44,15 +44,17 @@ static struct sock *nfnl = NULL;
|
||||
static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT];
|
||||
static DEFINE_MUTEX(nfnl_mutex);
|
||||
|
||||
static inline void nfnl_lock(void)
|
||||
void nfnl_lock(void)
|
||||
{
|
||||
mutex_lock(&nfnl_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfnl_lock);
|
||||
|
||||
static inline void nfnl_unlock(void)
|
||||
void nfnl_unlock(void)
|
||||
{
|
||||
mutex_unlock(&nfnl_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfnl_unlock);
|
||||
|
||||
int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
|
||||
{
|
||||
@@ -132,6 +134,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
return 0;
|
||||
|
||||
type = nlh->nlmsg_type;
|
||||
replay:
|
||||
ss = nfnetlink_get_subsys(type);
|
||||
if (!ss) {
|
||||
#ifdef CONFIG_KMOD
|
||||
@@ -165,7 +168,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
return nc->call(nfnl, skb, nlh, cda);
|
||||
err = nc->call(nfnl, skb, nlh, cda);
|
||||
if (err == -EAGAIN)
|
||||
goto replay;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user