Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
This commit is contained in:
@@ -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) \
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -1022,6 +1022,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IPV6_PRIVACY
|
||||||
/* Rule 7: Prefer public address
|
/* Rule 7: Prefer public address
|
||||||
* Note: prefer temprary address if use_tempaddr >= 2
|
* Note: prefer temprary address if use_tempaddr >= 2
|
||||||
*/
|
*/
|
||||||
@@ -1042,7 +1043,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
|
|||||||
if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
|
if (hiscore.attrs & IPV6_SADDR_SCORE_PRIVACY)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* Rule 8: Use longest matching prefix */
|
/* Rule 8: Use longest matching prefix */
|
||||||
if (hiscore.rule < 8)
|
if (hiscore.rule < 8)
|
||||||
hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
|
hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
|
||||||
|
@@ -525,6 +525,7 @@ ip6ip6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
|
|||||||
|
|
||||||
if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) {
|
if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) {
|
||||||
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
|
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
|
||||||
|
read_unlock(&ip6ip6_lock);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -128,7 +128,7 @@ void __nfa_fill(struct sk_buff *skb, int attrtype, int attrlen,
|
|||||||
memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size);
|
memset(NFA_DATA(nfa) + attrlen, 0, NFA_ALIGN(size) - size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
|
void nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
|
||||||
{
|
{
|
||||||
memset(tb, 0, sizeof(struct nfattr *) * maxattr);
|
memset(tb, 0, sizeof(struct nfattr *) * maxattr);
|
||||||
|
|
||||||
@@ -138,8 +138,6 @@ int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
|
|||||||
tb[flavor-1] = nfa;
|
tb[flavor-1] = nfa;
|
||||||
nfa = NFA_NEXT(nfa, len);
|
nfa = NFA_NEXT(nfa, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -242,15 +240,18 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
|
|||||||
ss = nfnetlink_get_subsys(type);
|
ss = nfnetlink_get_subsys(type);
|
||||||
if (!ss) {
|
if (!ss) {
|
||||||
#ifdef CONFIG_KMOD
|
#ifdef CONFIG_KMOD
|
||||||
/* don't call nfnl_shunlock, since it would reenter
|
if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
|
||||||
* with further packet processing */
|
/* don't call nfnl_shunlock, since it would reenter
|
||||||
up(&nfnl_sem);
|
* with further packet processing */
|
||||||
request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
|
up(&nfnl_sem);
|
||||||
nfnl_shlock();
|
request_module("nfnetlink-subsys-%d",
|
||||||
ss = nfnetlink_get_subsys(type);
|
NFNL_SUBSYS_ID(type));
|
||||||
|
nfnl_shlock();
|
||||||
|
ss = nfnetlink_get_subsys(type);
|
||||||
|
}
|
||||||
if (!ss)
|
if (!ss)
|
||||||
#endif
|
#endif
|
||||||
goto err_inval;
|
goto err_inval;
|
||||||
}
|
}
|
||||||
|
|
||||||
nc = nfnetlink_find_client(type, ss);
|
nc = nfnetlink_find_client(type, ss);
|
||||||
|
Reference in New Issue
Block a user