* [PATCH 12/72] netfilter: ctnetlink: missing validation of CTA_EXPECT_ZONE attribute
From: kaber @ 2010-10-21 15:18 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1287674399-31455-1-git-send-email-kaber@trash.net>
From: Pablo Neira Ayuso <pablo@netfilter.org>
This patch adds the missing validation of the CTA_EXPECT_ZONE
attribute in the ctnetlink code.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
net/netfilter/nf_conntrack_netlink.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 5bae1cd..37533a3 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1733,6 +1733,7 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
[CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 },
[CTA_EXPECT_ID] = { .type = NLA_U32 },
[CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING },
+ [CTA_EXPECT_ZONE] = { .type = NLA_U16 },
};
static int
--
1.7.1
^ permalink raw reply related
* [PATCH 11/72] netfilter: nf_nat: better error handling of nf_ct_expect_related() in helpers
From: kaber @ 2010-10-21 15:18 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1287674399-31455-1-git-send-email-kaber@trash.net>
From: Pablo Neira Ayuso <pablo@netfilter.org>
This patch improves the situation in which the expectation table is
full for conntrack NAT helpers. Basically, we give up if we don't
find a place in the table instead of looping over nf_ct_expect_related()
with a different port (we should only do this if it returns -EBUSY, for
-EMFILE or -ESHUTDOWN I think that it's better to skip this).
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
net/ipv4/netfilter/nf_nat_amanda.c | 9 +++++-
net/ipv4/netfilter/nf_nat_ftp.c | 9 +++++-
net/ipv4/netfilter/nf_nat_h323.c | 53 +++++++++++++++++++++++++++++++-----
net/ipv4/netfilter/nf_nat_irc.c | 9 +++++-
net/ipv4/netfilter/nf_nat_sip.c | 27 +++++++++++++++---
5 files changed, 93 insertions(+), 14 deletions(-)
diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c
index c31b876..0f23b3f 100644
--- a/net/ipv4/netfilter/nf_nat_amanda.c
+++ b/net/ipv4/netfilter/nf_nat_amanda.c
@@ -44,9 +44,16 @@ static unsigned int help(struct sk_buff *skb,
/* Try to get same port: if not, try to change it. */
for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ port = 0;
break;
+ }
}
if (port == 0)
diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c
index 86e0e84..dc73abb 100644
--- a/net/ipv4/netfilter/nf_nat_ftp.c
+++ b/net/ipv4/netfilter/nf_nat_ftp.c
@@ -79,9 +79,16 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb,
/* Try to get same port: if not, try to change it. */
for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ port = 0;
break;
+ }
}
if (port == 0)
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
index 5045196..790f316 100644
--- a/net/ipv4/netfilter/nf_nat_h323.c
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -222,13 +222,24 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get a pair of ports. */
for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);
nated_port != 0; nated_port += 2) {
+ int ret;
+
rtp_exp->tuple.dst.u.udp.port = htons(nated_port);
- if (nf_ct_expect_related(rtp_exp) == 0) {
+ ret = nf_ct_expect_related(rtp_exp);
+ if (ret == 0) {
rtcp_exp->tuple.dst.u.udp.port =
htons(nated_port + 1);
- if (nf_ct_expect_related(rtcp_exp) == 0)
+ ret = nf_ct_expect_related(rtcp_exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ nf_ct_unexpect_related(rtp_exp);
+ nated_port = 0;
break;
- nf_ct_unexpect_related(rtp_exp);
+ }
+ } else if (ret != -EBUSY) {
+ nated_port = 0;
+ break;
}
}
@@ -284,9 +295,16 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get same port: if not, try to change it. */
for (; nated_port != 0; nated_port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(nated_port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ nated_port = 0;
break;
+ }
}
if (nated_port == 0) { /* No port available */
@@ -334,9 +352,16 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get same port: if not, try to change it. */
for (; nated_port != 0; nated_port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(nated_port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
break;
+ else if (ret != -EBUSY) {
+ nated_port = 0;
+ break;
+ }
}
if (nated_port == 0) { /* No port available */
@@ -418,9 +443,16 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get same port: if not, try to change it. */
for (; nated_port != 0; nated_port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(nated_port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ nated_port = 0;
break;
+ }
}
if (nated_port == 0) { /* No port available */
@@ -500,9 +532,16 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
/* Try to get same port: if not, try to change it. */
for (nated_port = ntohs(port); nated_port != 0; nated_port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(nated_port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
break;
+ else if (ret != -EBUSY) {
+ nated_port = 0;
+ break;
+ }
}
if (nated_port == 0) { /* No port available */
diff --git a/net/ipv4/netfilter/nf_nat_irc.c b/net/ipv4/netfilter/nf_nat_irc.c
index ea83a88..535e1a8 100644
--- a/net/ipv4/netfilter/nf_nat_irc.c
+++ b/net/ipv4/netfilter/nf_nat_irc.c
@@ -45,9 +45,16 @@ static unsigned int help(struct sk_buff *skb,
/* Try to get same port: if not, try to change it. */
for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
+ int ret;
+
exp->tuple.dst.u.tcp.port = htons(port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ port = 0;
break;
+ }
}
if (port == 0)
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index 11b538d..e40cf78 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -307,9 +307,16 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int dataoff,
exp->expectfn = ip_nat_sip_expected;
for (; port != 0; port++) {
+ int ret;
+
exp->tuple.dst.u.udp.port = htons(port);
- if (nf_ct_expect_related(exp) == 0)
+ ret = nf_ct_expect_related(exp);
+ if (ret == 0)
+ break;
+ else if (ret != -EBUSY) {
+ port = 0;
break;
+ }
}
if (port == 0)
@@ -480,13 +487,25 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff,
/* Try to get same pair of ports: if not, try to change them. */
for (port = ntohs(rtp_exp->tuple.dst.u.udp.port);
port != 0; port += 2) {
+ int ret;
+
rtp_exp->tuple.dst.u.udp.port = htons(port);
- if (nf_ct_expect_related(rtp_exp) != 0)
+ ret = nf_ct_expect_related(rtp_exp);
+ if (ret == -EBUSY)
continue;
+ else if (ret < 0) {
+ port = 0;
+ break;
+ }
rtcp_exp->tuple.dst.u.udp.port = htons(port + 1);
- if (nf_ct_expect_related(rtcp_exp) == 0)
+ ret = nf_ct_expect_related(rtcp_exp);
+ if (ret == 0)
break;
- nf_ct_unexpect_related(rtp_exp);
+ else if (ret != -EBUSY) {
+ nf_ct_unexpect_related(rtp_exp);
+ port = 0;
+ break;
+ }
}
if (port == 0)
--
1.7.1
^ permalink raw reply related
* [PATCH 07/72] ipvs: netfilter connection tracking changes
From: kaber @ 2010-10-21 15:18 UTC (permalink / raw)
To: davem; +Cc: netfilter-devel, netdev
In-Reply-To: <1287674399-31455-1-git-send-email-kaber@trash.net>
From: Julian Anastasov <ja@ssi.bg>
Add more code to IPVS to work with Netfilter connection
tracking and fix some problems.
- Allow IPVS to be compiled without connection tracking as in
2.6.35 and before. This can avoid keeping conntracks for all
IPVS connections because this costs memory. ip_vs_ftp still
depends on connection tracking and NAT as implemented for 2.6.36.
- Add sysctl var "conntrack" to enable connection tracking for
all IPVS connections. For loaded IPVS directors it needs
tuning of nf_conntrack_max limit.
- Add IP_VS_CONN_F_NFCT connection flag to request the connection
to use connection tracking. This allows user space to provide this
flag, for example, in dest->conn_flags. This can be useful to
request connection tracking per real server instead of forcing it
for all connections with the "conntrack" sysctl. This flag is
set currently only by ip_vs_ftp and of course by "conntrack" sysctl.
- Add ip_vs_nfct.c file to hold all connection tracking code,
by this way main code should not depend of netfilter conntrack
support.
- Return back the ip_vs_post_routing handler as in 2.6.35 and use
skb->ipvs_property=1 to allow IPVS to work without connection
tracking
Connection tracking:
- most of the code is already in 2.6.36-rc
- alter conntrack reply tuple for LVS-NAT connections when first packet
from client is forwarded and conntrack state is NEW or RELATED.
Additionally, alter reply for RELATED connections from real server,
again for packet in original direction.
- add IP_VS_XMIT_TUNNEL to confirm conntrack (without altering
reply) for LVS-TUN early because we want to call nf_reset. It is
needed because we add IPIP header and the original conntrack
should be preserved, not destroyed. The transmitted IPIP packets
can reuse same conntrack, so we do not set skb->ipvs_property.
- try to destroy conntrack when the IPVS connection is destroyed.
It is not fatal if conntrack disappears before that, it depends
on the used timers.
Fix problems from long time:
- add skb->ip_summed = CHECKSUM_NONE for the LVS-TUN transmitters
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/linux/ip_vs.h | 2 +
include/net/ip_vs.h | 44 ++++++-
net/netfilter/ipvs/Kconfig | 13 ++-
net/netfilter/ipvs/Makefile | 5 +-
net/netfilter/ipvs/ip_vs_conn.c | 13 ++
net/netfilter/ipvs/ip_vs_core.c | 46 ++++++-
net/netfilter/ipvs/ip_vs_ctl.c | 12 ++
net/netfilter/ipvs/ip_vs_ftp.c | 146 +-------------------
net/netfilter/ipvs/ip_vs_nfct.c | 292 +++++++++++++++++++++++++++++++++++++++
net/netfilter/ipvs/ip_vs_xmit.c | 98 +++++++-------
10 files changed, 475 insertions(+), 196 deletions(-)
create mode 100644 net/netfilter/ipvs/ip_vs_nfct.c
diff --git a/include/linux/ip_vs.h b/include/linux/ip_vs.h
index 003d75f..df77286 100644
--- a/include/linux/ip_vs.h
+++ b/include/linux/ip_vs.h
@@ -90,10 +90,12 @@
#define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */
/* Flags that are not sent to backup server start from bit 16 */
+#define IP_VS_CONN_F_NFCT (1 << 16) /* use netfilter conntrack */
/* Connection flags from destination that can be changed by user space */
#define IP_VS_CONN_F_DEST_MASK (IP_VS_CONN_F_FWD_MASK | \
IP_VS_CONN_F_ONE_PACKET | \
+ IP_VS_CONN_F_NFCT | \
0)
#define IP_VS_SCHEDNAME_MAXLEN 16
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 62698a9..e8ec523 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -25,7 +25,9 @@
#include <linux/ip.h>
#include <linux/ipv6.h> /* for struct ipv6hdr */
#include <net/ipv6.h> /* for ipv6_addr_copy */
-
+#ifdef CONFIG_IP_VS_NFCT
+#include <net/netfilter/nf_conntrack.h>
+#endif
/* Connections' size value needed by ip_vs_ctl.c */
extern int ip_vs_conn_tab_size;
@@ -798,6 +800,7 @@ extern int sysctl_ip_vs_expire_nodest_conn;
extern int sysctl_ip_vs_expire_quiescent_template;
extern int sysctl_ip_vs_sync_threshold[2];
extern int sysctl_ip_vs_nat_icmp_send;
+extern int sysctl_ip_vs_conntrack;
extern struct ip_vs_stats ip_vs_stats;
extern const struct ctl_path net_vs_ctl_path[];
@@ -955,8 +958,47 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
return csum_partial(diff, sizeof(diff), oldsum);
}
+#ifdef CONFIG_IP_VS_NFCT
+/*
+ * Netfilter connection tracking
+ * (from ip_vs_nfct.c)
+ */
+static inline int ip_vs_conntrack_enabled(void)
+{
+ return sysctl_ip_vs_conntrack;
+}
+
extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
int outin);
+extern int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp);
+extern void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
+ struct ip_vs_conn *cp, u_int8_t proto,
+ const __be16 port, int from_rs);
+extern void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp);
+
+#else
+
+static inline int ip_vs_conntrack_enabled(void)
+{
+ return 0;
+}
+
+static inline void ip_vs_update_conntrack(struct sk_buff *skb,
+ struct ip_vs_conn *cp, int outin)
+{
+}
+
+static inline int ip_vs_confirm_conntrack(struct sk_buff *skb,
+ struct ip_vs_conn *cp)
+{
+ return NF_ACCEPT;
+}
+
+static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp)
+{
+}
+/* CONFIG_IP_VS_NFCT */
+#endif
#endif /* __KERNEL__ */
diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig
index 46a77d5..af3c9f4 100644
--- a/net/netfilter/ipvs/Kconfig
+++ b/net/netfilter/ipvs/Kconfig
@@ -3,7 +3,7 @@
#
menuconfig IP_VS
tristate "IP virtual server support"
- depends on NET && INET && NETFILTER && NF_CONNTRACK
+ depends on NET && INET && NETFILTER
---help---
IP Virtual Server support will let you build a high-performance
virtual server based on cluster of two or more real servers. This
@@ -235,7 +235,8 @@ comment 'IPVS application helper'
config IP_VS_FTP
tristate "FTP protocol helper"
- depends on IP_VS_PROTO_TCP && NF_NAT
+ depends on IP_VS_PROTO_TCP && NF_CONNTRACK && NF_NAT
+ select IP_VS_NFCT
---help---
FTP is a protocol that transfers IP address and/or port number in
the payload. In the virtual server via Network Address Translation,
@@ -247,4 +248,12 @@ config IP_VS_FTP
If you want to compile it in kernel, say Y. To compile it as a
module, choose M here. If unsure, say N.
+config IP_VS_NFCT
+ bool "Netfilter connection tracking"
+ depends on NF_CONNTRACK
+ ---help---
+ The Netfilter connection tracking support allows the IPVS
+ connection state to be exported to the Netfilter framework
+ for filtering purposes.
+
endif # IP_VS
diff --git a/net/netfilter/ipvs/Makefile b/net/netfilter/ipvs/Makefile
index e3baefd..349fe88 100644
--- a/net/netfilter/ipvs/Makefile
+++ b/net/netfilter/ipvs/Makefile
@@ -9,10 +9,13 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_UDP) += ip_vs_proto_udp.o
ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH_ESP) += ip_vs_proto_ah_esp.o
ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_SCTP) += ip_vs_proto_sctp.o
+ip_vs-extra_objs-y :=
+ip_vs-extra_objs-$(CONFIG_IP_VS_NFCT) += ip_vs_nfct.o
+
ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \
ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \
ip_vs_est.o ip_vs_proto.o \
- $(ip_vs_proto-objs-y)
+ $(ip_vs_proto-objs-y) $(ip_vs-extra_objs-y)
# IPVS core
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 9fe1da7..a970d96 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -721,6 +721,9 @@ static void ip_vs_conn_expire(unsigned long data)
if (cp->control)
ip_vs_control_del(cp);
+ if (cp->flags & IP_VS_CONN_F_NFCT)
+ ip_vs_conn_drop_conntrack(cp);
+
if (unlikely(cp->app != NULL))
ip_vs_unbind_app(cp);
ip_vs_unbind_dest(cp);
@@ -816,6 +819,16 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
if (unlikely(pp && atomic_read(&pp->appcnt)))
ip_vs_bind_app(cp, pp);
+ /*
+ * Allow conntrack to be preserved. By default, conntrack
+ * is created and destroyed for every packet.
+ * Sometimes keeping conntrack can be useful for
+ * IP_VS_CONN_F_ONE_PACKET too.
+ */
+
+ if (ip_vs_conntrack_enabled())
+ cp->flags |= IP_VS_CONN_F_NFCT;
+
/* Hash it in the ip_vs_conn_tab finally */
ip_vs_conn_hash(cp);
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 319991d..7fbc80d 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -537,6 +537,23 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
return NF_DROP;
}
+/*
+ * It is hooked before NF_IP_PRI_NAT_SRC at the NF_INET_POST_ROUTING
+ * chain and is used to avoid double NAT and confirmation when we do
+ * not want to keep the conntrack structure
+ */
+static unsigned int ip_vs_post_routing(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ if (!skb->ipvs_property)
+ return NF_ACCEPT;
+ /* The packet was sent from IPVS, exit this chain */
+ return NF_STOP;
+}
+
__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
{
return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
@@ -695,7 +712,10 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
/* do the statistics and put it back */
ip_vs_out_stats(cp, skb);
- skb->ipvs_property = 1;
+ if (!(cp->flags & IP_VS_CONN_F_NFCT))
+ skb->ipvs_property = 1;
+ else
+ ip_vs_update_conntrack(skb, cp, 0);
verdict = NF_ACCEPT;
out:
@@ -928,17 +948,19 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
ip_vs_out_stats(cp, skb);
ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
- ip_vs_update_conntrack(skb, cp, 0);
+ if (!(cp->flags & IP_VS_CONN_F_NFCT))
+ skb->ipvs_property = 1;
+ else
+ ip_vs_update_conntrack(skb, cp, 0);
ip_vs_conn_put(cp);
- skb->ipvs_property = 1;
-
LeaveFunction(11);
return NF_ACCEPT;
drop:
ip_vs_conn_put(cp);
kfree_skb(skb);
+ LeaveFunction(11);
return NF_STOLEN;
}
@@ -1483,6 +1505,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
.hooknum = NF_INET_FORWARD,
.priority = 99,
},
+ /* Before the netfilter connection tracking, exit from POST_ROUTING */
+ {
+ .hook = ip_vs_post_routing,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_INET_POST_ROUTING,
+ .priority = NF_IP_PRI_NAT_SRC-1,
+ },
#ifdef CONFIG_IP_VS_IPV6
/* After packet filtering, forward packet through VS/DR, VS/TUN,
* or VS/NAT(change destination), so that filtering rules can be
@@ -1511,6 +1541,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
.hooknum = NF_INET_FORWARD,
.priority = 99,
},
+ /* Before the netfilter connection tracking, exit from POST_ROUTING */
+ {
+ .hook = ip_vs_post_routing,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_INET_POST_ROUTING,
+ .priority = NF_IP6_PRI_NAT_SRC-1,
+ },
#endif
};
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 7bd41d2..d2d842f 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -88,6 +88,9 @@ int sysctl_ip_vs_expire_nodest_conn = 0;
int sysctl_ip_vs_expire_quiescent_template = 0;
int sysctl_ip_vs_sync_threshold[2] = { 3, 50 };
int sysctl_ip_vs_nat_icmp_send = 0;
+#ifdef CONFIG_IP_VS_NFCT
+int sysctl_ip_vs_conntrack;
+#endif
#ifdef CONFIG_IP_VS_DEBUG
@@ -1580,6 +1583,15 @@ static struct ctl_table vs_vars[] = {
.mode = 0644,
.proc_handler = proc_do_defense_mode,
},
+#ifdef CONFIG_IP_VS_NFCT
+ {
+ .procname = "conntrack",
+ .data = &sysctl_ip_vs_conntrack,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
{
.procname = "secure_tcp",
.data = &sysctl_ip_vs_secure_tcp,
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index 7e9af5b..9cd375f 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -20,17 +20,6 @@
*
* Author: Wouter Gadeyne
*
- *
- * Code for ip_vs_expect_related and ip_vs_expect_callback is taken from
- * http://www.ssi.bg/~ja/nfct/:
- *
- * ip_vs_nfct.c: Netfilter connection tracking support for IPVS
- *
- * Portions Copyright (C) 2001-2002
- * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland.
- *
- * Portions Copyright (C) 2003-2008
- * Julian Anastasov
*/
#define KMSG_COMPONENT "IPVS"
@@ -58,16 +47,6 @@
#define SERVER_STRING "227 Entering Passive Mode ("
#define CLIENT_STRING "PORT "
-#define FMT_TUPLE "%pI4:%u->%pI4:%u/%u"
-#define ARG_TUPLE(T) &(T)->src.u3.ip, ntohs((T)->src.u.all), \
- &(T)->dst.u3.ip, ntohs((T)->dst.u.all), \
- (T)->dst.protonum
-
-#define FMT_CONN "%pI4:%u->%pI4:%u->%pI4:%u/%u:%u"
-#define ARG_CONN(C) &((C)->caddr.ip), ntohs((C)->cport), \
- &((C)->vaddr.ip), ntohs((C)->vport), \
- &((C)->daddr.ip), ntohs((C)->dport), \
- (C)->protocol, (C)->state
/*
* List of ports (up to IP_VS_APP_MAX_PORTS) to be handled by helper
@@ -85,6 +64,8 @@ static int ip_vs_ftp_pasv;
static int
ip_vs_ftp_init_conn(struct ip_vs_app *app, struct ip_vs_conn *cp)
{
+ /* We use connection tracking for the command connection */
+ cp->flags |= IP_VS_CONN_F_NFCT;
return 0;
}
@@ -149,120 +130,6 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
}
/*
- * Called from init_conntrack() as expectfn handler.
- */
-static void
-ip_vs_expect_callback(struct nf_conn *ct,
- struct nf_conntrack_expect *exp)
-{
- struct nf_conntrack_tuple *orig, new_reply;
- struct ip_vs_conn *cp;
-
- if (exp->tuple.src.l3num != PF_INET)
- return;
-
- /*
- * We assume that no NF locks are held before this callback.
- * ip_vs_conn_out_get and ip_vs_conn_in_get should match their
- * expectations even if they use wildcard values, now we provide the
- * actual values from the newly created original conntrack direction.
- * The conntrack is confirmed when packet reaches IPVS hooks.
- */
-
- /* RS->CLIENT */
- orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
- cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum,
- &orig->src.u3, orig->src.u.tcp.port,
- &orig->dst.u3, orig->dst.u.tcp.port);
- if (cp) {
- /* Change reply CLIENT->RS to CLIENT->VS */
- new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
- IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", "
- FMT_TUPLE ", found inout cp=" FMT_CONN "\n",
- __func__, ct, ct->status,
- ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
- ARG_CONN(cp));
- new_reply.dst.u3 = cp->vaddr;
- new_reply.dst.u.tcp.port = cp->vport;
- IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE
- ", inout cp=" FMT_CONN "\n",
- __func__, ct,
- ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
- ARG_CONN(cp));
- goto alter;
- }
-
- /* CLIENT->VS */
- cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum,
- &orig->src.u3, orig->src.u.tcp.port,
- &orig->dst.u3, orig->dst.u.tcp.port);
- if (cp) {
- /* Change reply VS->CLIENT to RS->CLIENT */
- new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
- IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", "
- FMT_TUPLE ", found outin cp=" FMT_CONN "\n",
- __func__, ct, ct->status,
- ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
- ARG_CONN(cp));
- new_reply.src.u3 = cp->daddr;
- new_reply.src.u.tcp.port = cp->dport;
- IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", "
- FMT_TUPLE ", outin cp=" FMT_CONN "\n",
- __func__, ct,
- ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
- ARG_CONN(cp));
- goto alter;
- }
-
- IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuple=" FMT_TUPLE
- " - unknown expect\n",
- __func__, ct, ct->status, ARG_TUPLE(orig));
- return;
-
-alter:
- /* Never alter conntrack for non-NAT conns */
- if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ)
- nf_conntrack_alter_reply(ct, &new_reply);
- ip_vs_conn_put(cp);
- return;
-}
-
-/*
- * Create NF conntrack expectation with wildcard (optional) source port.
- * Then the default callback function will alter the reply and will confirm
- * the conntrack entry when the first packet comes.
- */
-static void
-ip_vs_expect_related(struct sk_buff *skb, struct nf_conn *ct,
- struct ip_vs_conn *cp, u_int8_t proto,
- const __be16 *port, int from_rs)
-{
- struct nf_conntrack_expect *exp;
-
- BUG_ON(!ct || ct == &nf_conntrack_untracked);
-
- exp = nf_ct_expect_alloc(ct);
- if (!exp)
- return;
-
- if (from_rs)
- nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
- nf_ct_l3num(ct), &cp->daddr, &cp->caddr,
- proto, port, &cp->cport);
- else
- nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT,
- nf_ct_l3num(ct), &cp->caddr, &cp->vaddr,
- proto, port, &cp->vport);
-
- exp->expectfn = ip_vs_expect_callback;
-
- IP_VS_DBG(7, "%s(): ct=%p, expect tuple=" FMT_TUPLE "\n",
- __func__, ct, ARG_TUPLE(&exp->tuple));
- nf_ct_expect_related(exp);
- nf_ct_expect_put(exp);
-}
-
-/*
* Look at outgoing ftp packets to catch the response to a PASV command
* from the server (inside-to-outside).
* When we see one, we build a connection entry with the client address,
@@ -335,7 +202,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
&cp->caddr, 0,
&cp->vaddr, port,
&from, port,
- IP_VS_CONN_F_NO_CPORT,
+ IP_VS_CONN_F_NO_CPORT |
+ IP_VS_CONN_F_NFCT,
cp->dest);
if (!n_cp)
return 0;
@@ -371,8 +239,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
start-data, end-start,
buf, buf_len);
if (ret)
- ip_vs_expect_related(skb, ct, n_cp,
- IPPROTO_TCP, NULL, 0);
+ ip_vs_nfct_expect_related(skb, ct, n_cp,
+ IPPROTO_TCP, 0, 0);
}
/*
@@ -487,7 +355,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
&to, port,
&cp->vaddr, htons(ntohs(cp->vport)-1),
&cp->daddr, htons(ntohs(cp->dport)-1),
- 0,
+ IP_VS_CONN_F_NFCT,
cp->dest);
if (!n_cp)
return 0;
diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c
new file mode 100644
index 0000000..c038458
--- /dev/null
+++ b/net/netfilter/ipvs/ip_vs_nfct.c
@@ -0,0 +1,292 @@
+/*
+ * ip_vs_nfct.c: Netfilter connection tracking support for IPVS
+ *
+ * Portions Copyright (C) 2001-2002
+ * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland.
+ *
+ * Portions Copyright (C) 2003-2010
+ * Julian Anastasov
+ *
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Authors:
+ * Ben North <ben@redfrontdoor.org>
+ * Julian Anastasov <ja@ssi.bg> Reorganize and sync with latest kernels
+ * Hannes Eder <heder@google.com> Extend NFCT support for FTP, ipvs match
+ *
+ *
+ * Current status:
+ *
+ * - provide conntrack confirmation for new and related connections, by
+ * this way we can see their proper conntrack state in all hooks
+ * - support for all forwarding methods, not only NAT
+ * - FTP support (NAT), ability to support other NAT apps with expectations
+ * - to correctly create expectations for related NAT connections the proper
+ * NF conntrack support must be already installed, eg. ip_vs_ftp requires
+ * nf_conntrack_ftp ... iptables_nat for the same ports (but no iptables
+ * NAT rules are needed)
+ * - alter reply for NAT when forwarding packet in original direction:
+ * conntrack from client in NEW or RELATED (Passive FTP DATA) state or
+ * when RELATED conntrack is created from real server (Active FTP DATA)
+ * - if iptables_nat is not loaded the Passive FTP will not work (the
+ * PASV response can not be NAT-ed) but Active FTP should work
+ *
+ */
+
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/compiler.h>
+#include <linux/vmalloc.h>
+#include <linux/skbuff.h>
+#include <net/ip.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <net/ip_vs.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_expect.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_zones.h>
+
+
+#define FMT_TUPLE "%pI4:%u->%pI4:%u/%u"
+#define ARG_TUPLE(T) &(T)->src.u3.ip, ntohs((T)->src.u.all), \
+ &(T)->dst.u3.ip, ntohs((T)->dst.u.all), \
+ (T)->dst.protonum
+
+#define FMT_CONN "%pI4:%u->%pI4:%u->%pI4:%u/%u:%u"
+#define ARG_CONN(C) &((C)->caddr.ip), ntohs((C)->cport), \
+ &((C)->vaddr.ip), ntohs((C)->vport), \
+ &((C)->daddr.ip), ntohs((C)->dport), \
+ (C)->protocol, (C)->state
+
+void
+ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin)
+{
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);
+ struct nf_conntrack_tuple new_tuple;
+
+ if (ct == NULL || nf_ct_is_confirmed(ct) || nf_ct_is_untracked(ct) ||
+ nf_ct_is_dying(ct))
+ return;
+
+ /* Never alter conntrack for non-NAT conns */
+ if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
+ return;
+
+ /* Alter reply only in original direction */
+ if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
+ return;
+
+ /*
+ * The connection is not yet in the hashtable, so we update it.
+ * CIP->VIP will remain the same, so leave the tuple in
+ * IP_CT_DIR_ORIGINAL untouched. When the reply comes back from the
+ * real-server we will see RIP->DIP.
+ */
+ new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ /*
+ * This will also take care of UDP and other protocols.
+ */
+ if (outin) {
+ new_tuple.src.u3 = cp->daddr;
+ if (new_tuple.dst.protonum != IPPROTO_ICMP &&
+ new_tuple.dst.protonum != IPPROTO_ICMPV6)
+ new_tuple.src.u.tcp.port = cp->dport;
+ } else {
+ new_tuple.dst.u3 = cp->vaddr;
+ if (new_tuple.dst.protonum != IPPROTO_ICMP &&
+ new_tuple.dst.protonum != IPPROTO_ICMPV6)
+ new_tuple.dst.u.tcp.port = cp->vport;
+ }
+ IP_VS_DBG(7, "%s: Updating conntrack ct=%p, status=0x%lX, "
+ "ctinfo=%d, old reply=" FMT_TUPLE
+ ", new reply=" FMT_TUPLE ", cp=" FMT_CONN "\n",
+ __func__, ct, ct->status, ctinfo,
+ ARG_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple),
+ ARG_TUPLE(&new_tuple), ARG_CONN(cp));
+ nf_conntrack_alter_reply(ct, &new_tuple);
+}
+
+int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp)
+{
+ return nf_conntrack_confirm(skb);
+}
+
+/*
+ * Called from init_conntrack() as expectfn handler.
+ */
+static void ip_vs_nfct_expect_callback(struct nf_conn *ct,
+ struct nf_conntrack_expect *exp)
+{
+ struct nf_conntrack_tuple *orig, new_reply;
+ struct ip_vs_conn *cp;
+
+ if (exp->tuple.src.l3num != PF_INET)
+ return;
+
+ /*
+ * We assume that no NF locks are held before this callback.
+ * ip_vs_conn_out_get and ip_vs_conn_in_get should match their
+ * expectations even if they use wildcard values, now we provide the
+ * actual values from the newly created original conntrack direction.
+ * The conntrack is confirmed when packet reaches IPVS hooks.
+ */
+
+ /* RS->CLIENT */
+ orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum,
+ &orig->src.u3, orig->src.u.tcp.port,
+ &orig->dst.u3, orig->dst.u.tcp.port);
+ if (cp) {
+ /* Change reply CLIENT->RS to CLIENT->VS */
+ new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", "
+ FMT_TUPLE ", found inout cp=" FMT_CONN "\n",
+ __func__, ct, ct->status,
+ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
+ ARG_CONN(cp));
+ new_reply.dst.u3 = cp->vaddr;
+ new_reply.dst.u.tcp.port = cp->vport;
+ IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE
+ ", inout cp=" FMT_CONN "\n",
+ __func__, ct,
+ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
+ ARG_CONN(cp));
+ goto alter;
+ }
+
+ /* CLIENT->VS */
+ cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum,
+ &orig->src.u3, orig->src.u.tcp.port,
+ &orig->dst.u3, orig->dst.u.tcp.port);
+ if (cp) {
+ /* Change reply VS->CLIENT to RS->CLIENT */
+ new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", "
+ FMT_TUPLE ", found outin cp=" FMT_CONN "\n",
+ __func__, ct, ct->status,
+ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
+ ARG_CONN(cp));
+ new_reply.src.u3 = cp->daddr;
+ new_reply.src.u.tcp.port = cp->dport;
+ IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", "
+ FMT_TUPLE ", outin cp=" FMT_CONN "\n",
+ __func__, ct,
+ ARG_TUPLE(orig), ARG_TUPLE(&new_reply),
+ ARG_CONN(cp));
+ goto alter;
+ }
+
+ IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuple=" FMT_TUPLE
+ " - unknown expect\n",
+ __func__, ct, ct->status, ARG_TUPLE(orig));
+ return;
+
+alter:
+ /* Never alter conntrack for non-NAT conns */
+ if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ)
+ nf_conntrack_alter_reply(ct, &new_reply);
+ ip_vs_conn_put(cp);
+ return;
+}
+
+/*
+ * Create NF conntrack expectation with wildcard (optional) source port.
+ * Then the default callback function will alter the reply and will confirm
+ * the conntrack entry when the first packet comes.
+ * Use port 0 to expect connection from any port.
+ */
+void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
+ struct ip_vs_conn *cp, u_int8_t proto,
+ const __be16 port, int from_rs)
+{
+ struct nf_conntrack_expect *exp;
+
+ if (ct == NULL || nf_ct_is_untracked(ct))
+ return;
+
+ exp = nf_ct_expect_alloc(ct);
+ if (!exp)
+ return;
+
+ nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct),
+ from_rs ? &cp->daddr : &cp->caddr,
+ from_rs ? &cp->caddr : &cp->vaddr,
+ proto, port ? &port : NULL,
+ from_rs ? &cp->cport : &cp->vport);
+
+ exp->expectfn = ip_vs_nfct_expect_callback;
+
+ IP_VS_DBG(7, "%s: ct=%p, expect tuple=" FMT_TUPLE "\n",
+ __func__, ct, ARG_TUPLE(&exp->tuple));
+ nf_ct_expect_related(exp);
+ nf_ct_expect_put(exp);
+}
+EXPORT_SYMBOL(ip_vs_nfct_expect_related);
+
+/*
+ * Our connection was terminated, try to drop the conntrack immediately
+ */
+void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp)
+{
+ struct nf_conntrack_tuple_hash *h;
+ struct nf_conn *ct;
+ struct nf_conntrack_tuple tuple;
+
+ if (!cp->cport)
+ return;
+
+ tuple = (struct nf_conntrack_tuple) {
+ .dst = { .protonum = cp->protocol, .dir = IP_CT_DIR_ORIGINAL } };
+ tuple.src.u3 = cp->caddr;
+ tuple.src.u.all = cp->cport;
+ tuple.src.l3num = cp->af;
+ tuple.dst.u3 = cp->vaddr;
+ tuple.dst.u.all = cp->vport;
+
+ IP_VS_DBG(7, "%s: dropping conntrack with tuple=" FMT_TUPLE
+ " for conn " FMT_CONN "\n",
+ __func__, ARG_TUPLE(&tuple), ARG_CONN(cp));
+
+ h = nf_conntrack_find_get(&init_net, NF_CT_DEFAULT_ZONE, &tuple);
+ if (h) {
+ ct = nf_ct_tuplehash_to_ctrack(h);
+ /* Show what happens instead of calling nf_ct_kill() */
+ if (del_timer(&ct->timeout)) {
+ IP_VS_DBG(7, "%s: ct=%p, deleted conntrack timer for tuple="
+ FMT_TUPLE "\n",
+ __func__, ct, ARG_TUPLE(&tuple));
+ if (ct->timeout.function)
+ ct->timeout.function(ct->timeout.data);
+ } else {
+ IP_VS_DBG(7, "%s: ct=%p, no conntrack timer for tuple="
+ FMT_TUPLE "\n",
+ __func__, ct, ARG_TUPLE(&tuple));
+ }
+ nf_ct_put(ct);
+ } else {
+ IP_VS_DBG(7, "%s: no conntrack for tuple=" FMT_TUPLE "\n",
+ __func__, ARG_TUPLE(&tuple));
+ }
+}
+
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 49df6be..8817afa 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -28,7 +28,6 @@
#include <net/ip6_route.h>
#include <linux/icmpv6.h>
#include <linux/netfilter.h>
-#include <net/netfilter/nf_conntrack.h>
#include <linux/netfilter_ipv4.h>
#include <net/ip_vs.h>
@@ -194,12 +193,37 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
dst_release(old_dst);
}
-#define IP_VS_XMIT(pf, skb, rt) \
+#define IP_VS_XMIT_TUNNEL(skb, cp) \
+({ \
+ int __ret = NF_ACCEPT; \
+ \
+ if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT)) \
+ __ret = ip_vs_confirm_conntrack(skb, cp); \
+ if (__ret == NF_ACCEPT) { \
+ nf_reset(skb); \
+ (skb)->ip_summed = CHECKSUM_NONE; \
+ } \
+ __ret; \
+})
+
+#define IP_VS_XMIT_NAT(pf, skb, cp) \
do { \
- (skb)->ipvs_property = 1; \
+ if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \
+ (skb)->ipvs_property = 1; \
+ else \
+ ip_vs_update_conntrack(skb, cp, 1); \
skb_forward_csum(skb); \
NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \
- (rt)->dst.dev, dst_output); \
+ skb_dst(skb)->dev, dst_output); \
+} while (0)
+
+#define IP_VS_XMIT(pf, skb, cp) \
+do { \
+ if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \
+ (skb)->ipvs_property = 1; \
+ skb_forward_csum(skb); \
+ NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \
+ skb_dst(skb)->dev, dst_output); \
} while (0)
@@ -271,7 +295,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV4, skb, cp);
LeaveFunction(10);
return NF_STOLEN;
@@ -335,7 +359,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV6, skb, cp);
LeaveFunction(10);
return NF_STOLEN;
@@ -349,36 +373,6 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
}
#endif
-void
-ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin)
-{
- struct nf_conn *ct = (struct nf_conn *)skb->nfct;
- struct nf_conntrack_tuple new_tuple;
-
- if (ct == NULL || nf_ct_is_untracked(ct) || nf_ct_is_confirmed(ct))
- return;
-
- /*
- * The connection is not yet in the hashtable, so we update it.
- * CIP->VIP will remain the same, so leave the tuple in
- * IP_CT_DIR_ORIGINAL untouched. When the reply comes back from the
- * real-server we will see RIP->DIP.
- */
- new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
- if (outin)
- new_tuple.src.u3 = cp->daddr;
- else
- new_tuple.dst.u3 = cp->vaddr;
- /*
- * This will also take care of UDP and other protocols.
- */
- if (outin)
- new_tuple.src.u.tcp.port = cp->dport;
- else
- new_tuple.dst.u.tcp.port = cp->vport;
- nf_conntrack_alter_reply(ct, &new_tuple);
-}
-
/*
* NAT transmitter (only for outside-to-inside nat forwarding)
* Not used for related ICMP
@@ -434,8 +428,6 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT");
- ip_vs_update_conntrack(skb, cp, 1);
-
/* FIXME: when application helper enlarges the packet and the length
is larger than the MTU of outgoing device, there will be still
MTU problem. */
@@ -443,7 +435,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
+ IP_VS_XMIT_NAT(NFPROTO_IPV4, skb, cp);
LeaveFunction(10);
return NF_STOLEN;
@@ -451,8 +443,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
tx_error_icmp:
dst_link_failure(skb);
tx_error:
- LeaveFunction(10);
kfree_skb(skb);
+ LeaveFunction(10);
return NF_STOLEN;
tx_error_put:
ip_rt_put(rt);
@@ -512,8 +504,6 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT");
- ip_vs_update_conntrack(skb, cp, 1);
-
/* FIXME: when application helper enlarges the packet and the length
is larger than the MTU of outgoing device, there will be still
MTU problem. */
@@ -521,7 +511,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
+ IP_VS_XMIT_NAT(NFPROTO_IPV6, skb, cp);
LeaveFunction(10);
return NF_STOLEN;
@@ -571,6 +561,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
int mtu;
+ int ret;
EnterFunction(10);
@@ -655,7 +646,11 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- ip_local_out(skb);
+ ret = IP_VS_XMIT_TUNNEL(skb, cp);
+ if (ret == NF_ACCEPT)
+ ip_local_out(skb);
+ else if (ret == NF_DROP)
+ kfree_skb(skb);
LeaveFunction(10);
@@ -681,6 +676,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
struct ipv6hdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
int mtu;
+ int ret;
EnterFunction(10);
@@ -761,7 +757,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- ip6_local_out(skb);
+ ret = IP_VS_XMIT_TUNNEL(skb, cp);
+ if (ret == NF_ACCEPT)
+ ip6_local_out(skb);
+ else if (ret == NF_DROP)
+ kfree_skb(skb);
LeaveFunction(10);
@@ -820,7 +820,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV4, skb, cp);
LeaveFunction(10);
return NF_STOLEN;
@@ -873,7 +873,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV6, skb, cp);
LeaveFunction(10);
return NF_STOLEN;
@@ -947,7 +947,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV4, skb, cp);
rc = NF_STOLEN;
goto out;
@@ -1022,7 +1022,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
/* Another hack: avoid icmp_send in ip_fragment */
skb->local_df = 1;
- IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
+ IP_VS_XMIT(NFPROTO_IPV6, skb, cp);
rc = NF_STOLEN;
goto out;
--
1.7.1
^ permalink raw reply related
* Re: [RFC PATCH 1/9] ipvs network name space aware
From: Paul E. McKenney @ 2010-10-21 15:18 UTC (permalink / raw)
To: Eric Dumazet
Cc: Hans Schillstrom, Daniel Lezcano, lvs-devel@vger.kernel.org,
netdev@vger.kernel.org, netfilter-devel@vger.kernel.org,
horms@verge.net.au, ja@ssi.bg, wensong@linux-vs.org
In-Reply-To: <1287648072.6871.15.camel@edumazet-laptop>
On Thu, Oct 21, 2010 at 10:01:12AM +0200, Eric Dumazet wrote:
> Le jeudi 21 octobre 2010 à 09:45 +0200, Hans Schillstrom a écrit :
> > I do have this (and some debuging)
> > __rcu_read_lock()
> > => 0xffffffff8108bcf3 <+0>: push %rbp
> > 0xffffffff8108bcf4 <+1>: mov %rsp,%rbp
> > 0xffffffff8108bcf7 <+4>: nopl 0x0(%rax,%rax,1)
> > 0xffffffff8108bcfc <+9>: mov %gs:0xb540,%rax
> > 0xffffffff8108bd05 <+18>: mov 0x108(%rax),%edx
> > 0xffffffff8108bd0b <+24>: inc %edx
> > 0xffffffff8108bd0d <+26>: mov %edx,0x108(%rax)
> > 0xffffffff8108bd13 <+32>: leaveq
> > 0xffffffff8108bd14 <+33>: retq
> >
> > which is not that many, actually imprerssing few instructions :-)
>
> nopl 0x0(%rax,%rax,1) is a filler because of extra instrumentation in
> your kernel.
>
> Maybe you could find out why your compiler dont use
>
> incl 0x108(%rax)
>
> instead of
>
> mov 0x108(%rax),%edx
> inc %edx
> mov %edx,0x108(%rax)
>
>
> So rcu_read_lock() is really _two_ instructions.
>
> I agree with Paul with the "few" qualification... :-)
Thank you! ;-)
And the reason for the three-instruction shuffle is that Hans's kernel
does not yet contain commit 80dcf60e. That commit is on its way upstream,
and will hopefully make the current merge window.
Thanx, Paul
^ permalink raw reply
* Re: [PATCH] ibmveth: Increase default copybreak limits to 2k
From: Robert Jennings @ 2010-10-21 15:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20101021.074525.71113963.davem@davemloft.net>
* David Miller (davem@davemloft.net) wrote:
> From: Robert Jennings <rcj@linux.vnet.ibm.com>
>
> > Increase the copybreak limits for rx and tx from 128 bytes
> > to 2048 bytes. These limits were added by commits
> > 8d86c61ae41d9068fd5e5cc01a4abd53c4fe3ab5 and
> > c08cc3ccebd46dce44d13a8ce81d249e687eeb8a to make use of a
> > bounce buffer for packets below 128 bytes. This avoids
> > tearing down and creating a TCE entry.
> >
> > Performance testing shows that this default limit can be
> > increased from 128 to 2048 for both rx and tx copybreak.
> > This resulted in ~10% throughput increase for for packets
> > that fit this limit without affecting performance for larger
> > packets.
> >
> > Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
>
> For a default MTU of 1500 this means the copybreak will
> never be used.
>
> This makes absolutely no sense, are you doing these tests
> with Jumbo frames?
The value of copybreak is the point where we stop using the bounce
buffer and start to copy data to new buffers; having the overhead of
additional TCE entry setup/teardown. For the default MTU of 1500,
increasing the copybreak value to 2k will result in all packets using
the bounce buffer now. Expanding the use of the bounce buffer up to 2k
with the default MTU resulted in ~10% throughput improvement.
This was also tested with jumbo frames to verify that larger than
2k we don't use the bounce buffer and that there is no performance
regression.
I can repost the patch with these clarifications in the log message
if you would like.
--Rob Jennings
^ permalink raw reply
* Re: [RFC PATCH 1/9] ipvs network name space aware
From: Paul E. McKenney @ 2010-10-21 15:16 UTC (permalink / raw)
To: Eric Dumazet
Cc: Hans Schillstrom, Daniel Lezcano, lvs-devel@vger.kernel.org,
netdev@vger.kernel.org, netfilter-devel@vger.kernel.org,
horms@verge.net.au, ja@ssi.bg, wensong@linux-vs.org
In-Reply-To: <1287651504.6871.44.camel@edumazet-laptop>
On Thu, Oct 21, 2010 at 10:58:24AM +0200, Eric Dumazet wrote:
>
> > You said that there were a lot of "stepi" commands to get through
> > rcu_read_lock() on x86_64. This is quite surprising, especially if you
> > built with CONFIG_RCU_TREE. Even if you built with CONFIG_PREEMPT_RCU_TREE,
> > you should only see something like the following from rcu_read_lock():
> >
> > 000000b7 <__rcu_read_lock>:
> > b7: 55 push %ebp
> > b8: 64 a1 00 00 00 00 mov %fs:0x0,%eax
> > be: ff 80 80 01 00 00 incl 0x180(%eax)
> > c4: 89 e5 mov %esp,%ebp
> > c6: 5d pop %ebp
> > c7: c3 ret
> >
> > Unless you have some sort of debugging options turned on. Or unless
> > six instructions counts for "quite many" stepi commands. ;-)
>
> Paul, this should be inlined, dont you think ?
Indeed it should!!! It is out-of-line due to header-file issues.
Lai Jiangshan proposed a change to kbuild to allow it to be inlined as
part of his ring-RCU patch, and I have asked him to submit a version
of that for Tree and Tiny preemptible RCU. This is the usual trick of
having the build system compile the data structure and emit offsets,
which are then used in the main kernel build. (Yes, I did something
similar in DYNIX/ptx, but never managed to work up the courage to attempt
the equivalent in Linux's kbuild, so props to Lai!)
> Also, I dont understand why we use ACCESS_ONCE() in rcu_read_lock()
>
> ACCESS_ONCE(current->rcu_read_lock_nesting)++;
>
> Apparently, some compilers are a bit noisy here.
>
> mov 0x1b0(%rdx),%eax
> inc %eax
> mov %eax,0x1b0(%rdx)
>
> instead of :
>
> incl 0x1b0(%rax)
>
> So if the ACCESS_ONCE() is needed, we might add a comment, because it's
> not obvious ;)
Here is what it looks like in my -rcu tree:
void __rcu_read_lock(void)
{
current->rcu_read_lock_nesting++;
barrier(); /* needed if we ever invoke rcu_read_lock in rcutree.c */
}
So yes, I finally did convince myself that the ACCESS_ONCE was not
needed. ;-)
This is not yet in mainline, but Ingo sent the series containing this
commit (80dcf60e) to Linus earlier today, so there is hope!
Thanx, Paul
^ permalink raw reply
* Re: NET_NS: unregister_netdevice: waiting for lo to become free (adding ipv6 address to interface)
From: Michael Leun @ 2010-10-21 15:15 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Greg KH, netdev, davem, linux-kernel, Alexey Dobriyan,
Patrick McHardy
In-Reply-To: <20100805134707.0442a7b1@xenia.leun.net>
Hi,
unfortunately the bug described below originally reported in 2.6.35-rcX
is still there in 2.6.36.
Is there anything I might do to help fix it (besides fixing it myself,
I do not have the knowhow)?
On Thu, 5 Aug 2010 13:47:07 +0200
Michael Leun <lkml20100708@newton.leun.net> wrote:
[...]
> Putting an ipv6 address on a device seems to be the trigger:
>
> OrigNS > # ip link add type veth
> OrigNS > # ip link set dev veth0 up
> OrigNS > # unshare -n /bin/bash
> NewNS > # echo $$
> <SomePID>
> OrigNS > # ip link set dev veth1 netns <SomePID> # this, of course is
> on a different terminal NewNS > # ip link set dev veth1 up
> NewNS > # ip -6 addr add dev veth1 fd50:dead:beef::1/64
> NewNS > # exit
>
> Yields
>
> kernel: unregister_netdevice: waiting for veth1 to become free. Usage
> count = 3
>
> Oh - its veth1 this time, not lo - add an "ip link set up dev lo" in
> the above scenario just after the unshare, and you get the message
> with lo.
>
> One might ask, if
>
> > # unshare -n /bin/bash
> > # ip link set up dev lo
> > # ip -6 addr add dev veth1 fd50:dead:beef::1/64
> > # exit
>
> also does the trick, so I tried it - and it does NOT.
>
> In the above scenario, not setting veth0 and veth1 up also makes it
> not happen. Only setting veth1 up also is not enough (seems to need
> to be "really up" what as you shurely know with veth is only the case
> when both sides are up).
>
> I hope, this makes it somewhat easier to track that down.
--
MfG,
Michael Leun
^ permalink raw reply
* [PATCH] can: flexcan: fix use after free of priv
From: Marc Kleine-Budde @ 2010-10-21 15:07 UTC (permalink / raw)
To: socketcan-core-0fE9KPoRgkgATYTw5x5z8w
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Marc Kleine-Budde
The priv is part of the memory allocated by alloc_candev().
This patch moved the free it after last usage of priv.
Signed-off-by: Marc Kleine-Budde <mkl-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
The following changes since commit 27b75c95f10d249574d9c4cb9dab878107faede8:
Eric Dumazet (1):
net: avoid RCU for NOCACHE dst
are available in the git repository at:
git://git.pengutronix.de/git/mkl/linux-2.6.git can/flexcan-for-net-next
Marc Kleine-Budde (1):
can: flexcan: fix use after free of priv
drivers/net/can/flexcan.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index ef443a0..d499056 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -992,7 +992,6 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
unregister_flexcandev(dev);
platform_set_drvdata(pdev, NULL);
- free_candev(dev);
iounmap(priv->base);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1000,6 +999,8 @@ static int __devexit flexcan_remove(struct platform_device *pdev)
clk_put(priv->clk);
+ free_candev(dev);
+
return 0;
}
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH v2 02/22] bitops: rename generic little-endian bitops functions
From: Arnd Bergmann @ 2010-10-21 15:07 UTC (permalink / raw)
To: Akinobu Mita
Cc: linux-kernel, linux-arch, Christoph Hellwig, Andrew Morton,
Hans-Christian Egtvedt, Geert Uytterhoeven, Roman Zippel,
Andreas Schwab, linux-m68k, Greg Ungerer, Benjamin Herrenschmidt,
Paul Mackerras, linuxppc-dev, Andy Grover, rds-devel,
David S. Miller, netdev, Avi Kivity, Marcelo Tosatti, kvm
In-Reply-To: <1287672077-5797-3-git-send-email-akinobu.mita@gmail.com>
On Thursday 21 October 2010, Akinobu Mita wrote:
> As a preparation for providing little-endian bitops for all architectures,
> This removes generic_ prefix from little-endian bitops function names
> in asm-generic/bitops/le.h.
>
> s/generic_find_next_le_bit/find_next_le_bit/
> s/generic_find_next_zero_le_bit/find_next_zero_le_bit/
> s/generic_find_first_zero_le_bit/find_first_zero_le_bit/
> s/generic___test_and_set_le_bit/__test_and_set_le_bit/
> s/generic___test_and_clear_le_bit/__test_and_clear_le_bit/
> s/generic_test_le_bit/test_le_bit/
> s/generic___set_le_bit/__set_le_bit/
> s/generic___clear_le_bit/__clear_le_bit/
> s/generic_test_and_set_le_bit/test_and_set_le_bit/
> s/generic_test_and_clear_le_bit/test_and_clear_le_bit/
>
> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> Cc: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Roman Zippel <zippel@linux-m68k.org>
> Cc: Andreas Schwab <schwab@linux-m68k.org>
> Cc: linux-m68k@lists.linux-m68k.org
> Cc: Greg Ungerer <gerg@uclinux.org>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: Andy Grover <andy.grover@oracle.com>
> Cc: rds-devel@oss.oracle.com
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: netdev@vger.kernel.org
> Cc: Avi Kivity <avi@redhat.com>
> Cc: Marcelo Tosatti <mtosatti@redhat.com>
> Cc: kvm@vger.kernel.org
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* Re: [BUG] problems with "ip xfrm" on 32-bit userspace with 64-bit kernel
From: Chris Friesen @ 2010-10-21 15:05 UTC (permalink / raw)
To: Florian Westphal; +Cc: netdev, Linux Kernel Mailing List
In-Reply-To: <20101021075056.GE15247@Chamillionaire.breakpoint.cc>
On 10/21/2010 01:50 AM, Florian Westphal wrote:
> Chris Friesen <chris.friesen@genband.com> wrote:
>> We've run into a 32/64 compatibility problem with iproute2. The "ip
>> xfrm monitor acquire" command doesn't work properly due to struct size
>> mismatches between kernel and userspace.
>
> Yes. See archives for 'xfrm: add x86 CONFIG_COMPAT support'
> (http://marc.info/?t=127050655600003&r=1&w=2)
>
> for a discussion on why the patch set to fix this was rejected.
Interesting discussion. Kind of sucks for people trying to use it though.
How do distros resolve this? Do they build iproute2 as a 64-bit package
or something?
Chris
--
Chris Friesen
Software Developer
GENBAND
chris.friesen@genband.com
www.genband.com
^ permalink raw reply
* RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan accleration.
From: Vladislav Zolotarov @ 2010-10-21 14:50 UTC (permalink / raw)
To: Jesse Gross, David Miller
Cc: netdev@vger.kernel.org, Hao Zheng, Eilon Greenstein
In-Reply-To: <8628FE4E7912BF47A96AE7DD7BAC0AADDDEE429137@SJEXCHCCR02.corp.ad.broadcom.com>
> -----Original Message-----
> From: Vladislav Zolotarov
> Sent: Thursday, October 21, 2010 4:03 PM
> To: Vladislav Zolotarov; Jesse Gross; David Miller
> Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> Subject: RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> accleration.
>
>
>
> > -----Original Message-----
> > From: netdev-owner@vger.kernel.org [mailto:netdev-
> > owner@vger.kernel.org] On Behalf Of Vladislav Zolotarov
> > Sent: Thursday, October 21, 2010 3:55 PM
> > To: Jesse Gross; David Miller
> > Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> > Subject: RE: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> > accleration.
> >
> >
> >
> > > -----Original Message-----
> > > From: netdev-owner@vger.kernel.org [mailto:netdev-
> > > owner@vger.kernel.org] On Behalf Of Jesse Gross
> > > Sent: Thursday, October 21, 2010 1:56 AM
> > > To: David Miller
> > > Cc: netdev@vger.kernel.org; Hao Zheng; Eilon Greenstein
> > > Subject: [PATCH v2 11/14] bnx2x: Update bnx2x to use new vlan
> > > accleration.
> > >
> > > From: Hao Zheng <hzheng@nicira.com>
> > >
> > > Make the bnx2x driver use the new vlan accleration model.
> > >
> > > Signed-off-by: Hao Zheng <hzheng@nicira.com>
> > > Signed-off-by: Jesse Gross <jesse@nicira.com>
> > > CC: Eilon Greenstein <eilong@broadcom.com>
> > > ---
> > > drivers/net/bnx2x/bnx2x.h | 10 ------
> > > drivers/net/bnx2x/bnx2x_cmn.c | 60 +++++++------------------
> --
> > --
> > > --------
> > > drivers/net/bnx2x/bnx2x_ethtool.c | 33 ++++++++++----------
> > > drivers/net/bnx2x/bnx2x_main.c | 8 -----
> > > 4 files changed, 27 insertions(+), 84 deletions(-)
> > >
> > > diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
> > > index 3bf236b..9571ecf 100644
> > > --- a/drivers/net/bnx2x/bnx2x.h
> > > +++ b/drivers/net/bnx2x/bnx2x.h
> > > @@ -24,10 +24,6 @@
> > > #define DRV_MODULE_RELDATE "2010/10/19"
> > > #define BNX2X_BC_VER 0x040200
> > >
> > > -#if defined(CONFIG_VLAN_8021Q) ||
> defined(CONFIG_VLAN_8021Q_MODULE)
> > > -#define BCM_VLAN 1
> > > -#endif
> > > -
> > > #define BNX2X_MULTI_QUEUE
> > >
> > > #define BNX2X_NEW_NAPI
> > > @@ -858,10 +854,6 @@ struct bnx2x {
> > >
> > > int tx_ring_size;
> > >
> > > -#ifdef BCM_VLAN
> > > - struct vlan_group *vlgrp;
> > > -#endif
> > > -
> > > u32 rx_csum;
> > > u32 rx_buf_size;
> > > /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
> > > @@ -925,8 +917,6 @@ struct bnx2x {
> > > #define NO_MCP_FLAG 0x100
> > > #define DISABLE_MSI_FLAG 0x200
> > > #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
> > > -#define HW_VLAN_TX_FLAG 0x400
> > > -#define HW_VLAN_RX_FLAG 0x800
> > > #define MF_FUNC_DIS 0x1000
> > >
> > > int pf_num; /* absolute PF number */
> > > diff --git a/drivers/net/bnx2x/bnx2x_cmn.c
> > > b/drivers/net/bnx2x/bnx2x_cmn.c
> > > index 6905b2e..bc58375 100644
> > > --- a/drivers/net/bnx2x/bnx2x_cmn.c
> > > +++ b/drivers/net/bnx2x/bnx2x_cmn.c
> > > @@ -16,16 +16,13 @@
> > > */
> > >
> > > #include <linux/etherdevice.h>
> > > +#include <linux/if_vlan.h>
> > > #include <linux/ip.h>
> > > #include <net/ipv6.h>
> > > #include <net/ip6_checksum.h>
> > > #include <linux/firmware.h>
> > > #include "bnx2x_cmn.h"
> > >
> > > -#ifdef BCM_VLAN
> > > -#include <linux/if_vlan.h>
> > > -#endif
> > > -
> > > #include "bnx2x_init.h"
> > >
> > >
> > > @@ -346,13 +343,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> > > struct bnx2x_fastpath *fp,
> > > if (likely(new_skb)) {
> > > /* fix ip xsum and give it to the stack */
> > > /* (no need to map the new skb) */
> > > -#ifdef BCM_VLAN
> > > - int is_vlan_cqe =
> > > - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > > - PARSING_FLAGS_VLAN);
> > > - int is_not_hwaccel_vlan_cqe =
> > > - (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG)));
> > > -#endif
> > >
> > > prefetch(skb);
> > > prefetch(((char *)(skb)) + L1_CACHE_BYTES);
> > > @@ -377,28 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp,
> > > struct bnx2x_fastpath *fp,
> > > struct iphdr *iph;
> > >
> > > iph = (struct iphdr *)skb->data;
> > > -#ifdef BCM_VLAN
> > > - /* If there is no Rx VLAN offloading -
> > > - take VLAN tag into an account */
> > > - if (unlikely(is_not_hwaccel_vlan_cqe))
> > > - iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN);
> > > -#endif
> > > iph->check = 0;
> > > iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
> > > }
> > >
> > > if (!bnx2x_fill_frag_skb(bp, fp, skb,
> > > &cqe->fast_path_cqe, cqe_idx)) {
> > > -#ifdef BCM_VLAN
> > > - if ((bp->vlgrp != NULL) &&
> > > - (le16_to_cpu(cqe->fast_path_cqe.
> > > - pars_flags.flags) & PARSING_FLAGS_VLAN))
> > > - vlan_gro_receive(&fp->napi, bp->vlgrp,
> > > + if ((le16_to_cpu(cqe->fast_path_cqe.
> > > + pars_flags.flags) & PARSING_FLAGS_VLAN))
> > > + __vlan_hwaccel_put_tag(skb,
> > > le16_to_cpu(cqe->fast_path_cqe.
> > > - vlan_tag), skb);
> > > - else
> > > -#endif
> > > - napi_gro_receive(&fp->napi, skb);
> > > + vlan_tag));
> > > + napi_gro_receive(&fp->napi, skb);
> > > } else {
> > > DP(NETIF_MSG_RX_STATUS, "Failed to allocate new
> > > pages"
> > > " - dropping packet!\n");
> > > @@ -633,15 +613,11 @@ reuse_rx:
> > >
> > > skb_record_rx_queue(skb, fp->index);
> > >
> > > -#ifdef BCM_VLAN
> > > - if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
> > > - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > > - PARSING_FLAGS_VLAN))
> > > - vlan_gro_receive(&fp->napi, bp->vlgrp,
> > > - le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb);
> > > - else
> > > -#endif
> > > - napi_gro_receive(&fp->napi, skb);
> > > + if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
> > > + PARSING_FLAGS_VLAN)
> > > + __vlan_hwaccel_put_tag(skb,
> > > + le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
> > > + napi_gro_receive(&fp->napi, skb);
> > >
> > >
> > > next_rx:
> > > @@ -2025,14 +2001,12 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff
> > > *skb, struct net_device *dev)
> > > "sending pkt %u @%p next_idx %u bd %u @%p\n",
> > > pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
> > >
> > > -#ifdef BCM_VLAN
> > > if (vlan_tx_tag_present(skb)) {
> > > tx_start_bd->vlan_or_ethertype =
> > > cpu_to_le16(vlan_tx_tag_get(skb));
> > > tx_start_bd->bd_flags.as_bitfield |=
> > > (X_ETH_OUTBAND_VLAN <<
> > > ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
> > > } else
> > > -#endif
> > > tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
> > >
> > > /* turn on parsing and get a BD */
> > > @@ -2317,18 +2291,6 @@ void bnx2x_tx_timeout(struct net_device
> *dev)
> > > schedule_delayed_work(&bp->reset_task, 0);
> > > }
> > >
> > > -#ifdef BCM_VLAN
> > > -/* called with rtnl_lock */
> > > -void bnx2x_vlan_rx_register(struct net_device *dev,
> > > - struct vlan_group *vlgrp)
> > > -{
> > > - struct bnx2x *bp = netdev_priv(dev);
> > > -
> > > - bp->vlgrp = vlgrp;
> > > -}
> > > -
> > > -#endif
> > > -
> > > int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
> > > {
> > > struct net_device *dev = pci_get_drvdata(pdev);
> > > diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c
> > > b/drivers/net/bnx2x/bnx2x_ethtool.c
> > > index 54fe061..daefef6 100644
> > > --- a/drivers/net/bnx2x/bnx2x_ethtool.c
> > > +++ b/drivers/net/bnx2x/bnx2x_ethtool.c
> > > @@ -1117,35 +1117,34 @@ static int bnx2x_set_flags(struct
> net_device
> > > *dev, u32 data)
> > > int changed = 0;
> > > int rc = 0;
> > >
> > > - if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH))
> > > - return -EINVAL;
> > > -
> > > if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
> > > printk(KERN_ERR "Handling parity error recovery. Try again
> > > later\n");
> > > return -EAGAIN;
> > > }
> > >
> > > + if (!(data & ETH_FLAG_RXVLAN))
> > > + return -EOPNOTSUPP;
> > > +
> > > + if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
> > > + return -EINVAL;
> > > +
> > > + rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO |
> > > ETH_FLAG_RXVLAN |
> > > + ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
> > > + if (rc)
> > > + return rc;
> > > +
> > > /* TPA requires Rx CSUM offloading */
> > > if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
> > > - if (!bp->disable_tpa) {
> > > - if (!(dev->features & NETIF_F_LRO)) {
> > > - dev->features |= NETIF_F_LRO;
> > > - bp->flags |= TPA_ENABLE_FLAG;
> > > - changed = 1;
> > > - }
> > > - } else
> > > - rc = -EINVAL;
> > > - } else if (dev->features & NETIF_F_LRO) {
> > > + if (!(bp->flags & TPA_ENABLE_FLAG)) {
> > > + bp->flags |= TPA_ENABLE_FLAG;
> > > + changed = 1;
> > > + }
> > > + } else if (bp->flags & TPA_ENABLE_FLAG) {
> > > dev->features &= ~NETIF_F_LRO;
> > > bp->flags &= ~TPA_ENABLE_FLAG;
> > > changed = 1;
> > > }
> > >
> > > - if (data & ETH_FLAG_RXHASH)
> > > - dev->features |= NETIF_F_RXHASH;
> > > - else
> > > - dev->features &= ~NETIF_F_RXHASH;
> > > -
> > > if (changed && netif_running(dev)) {
> > > bnx2x_nic_unload(bp, UNLOAD_NORMAL);
> > > rc = bnx2x_nic_load(bp, LOAD_NORMAL);
> > > diff --git a/drivers/net/bnx2x/bnx2x_main.c
> > > b/drivers/net/bnx2x/bnx2x_main.c
> > > index f22e283..ff99a2f 100644
> > > --- a/drivers/net/bnx2x/bnx2x_main.c
> > > +++ b/drivers/net/bnx2x/bnx2x_main.c
> > > @@ -2371,10 +2371,8 @@ static inline u16 bnx2x_get_cl_flags(struct
> > > bnx2x *bp,
> > > flags |= QUEUE_FLG_HC;
> > > flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0;
> > >
> > > -#ifdef BCM_VLAN
> > > flags |= QUEUE_FLG_VLAN;
> > > DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
> > > -#endif
> > >
> > > if (!fp->disable_tpa)
> > > flags |= QUEUE_FLG_TPA;
> > > @@ -8630,9 +8628,6 @@ static const struct net_device_ops
> > > bnx2x_netdev_ops = {
> > > .ndo_do_ioctl = bnx2x_ioctl,
> > > .ndo_change_mtu = bnx2x_change_mtu,
> > > .ndo_tx_timeout = bnx2x_tx_timeout,
> > > -#ifdef BCM_VLAN
> > > - .ndo_vlan_rx_register = bnx2x_vlan_rx_register,
> > > -#endif
> > > #ifdef CONFIG_NET_POLL_CONTROLLER
> > > .ndo_poll_controller = poll_bnx2x,
> > > #endif
> > > @@ -8764,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct
> > > pci_dev *pdev,
> > > dev->features |= NETIF_F_HIGHDMA;
> > > dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> > > dev->features |= NETIF_F_TSO6;
> > > -#ifdef BCM_VLAN
> > > dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
> > > - bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
> > >
> > > dev->vlan_features |= NETIF_F_SG;
> > > dev->vlan_features |= NETIF_F_HW_CSUM;
> > > @@ -8774,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct
> > > pci_dev *pdev,
> > > dev->vlan_features |= NETIF_F_HIGHDMA;
> > > dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
> > > dev->vlan_features |= NETIF_F_TSO6;
> > > -#endif
> > >
> > > /* get_port_hwinfo() will set prtad and mmds properly */
> > > bp->mdio.prtad = MDIO_PRTAD_NONE;
> > > --
> > > 1.7.1
> >
> > Guys, when I compiled the kernel with these patches without VLAN
> > support (CONFIG_VLAN_8021Q is not set) and tried to send VLAN tagged
> > frames from the remote side to the bnx2x interface the kernel
> panicked.
> >
> > The stack trace got cut with the __netif_receive_skb() on top by the
> > IPKVM and I'll have to connect a serial to get it all. But until I
> > did that maybe somebody will have any ideas anyway...
> >
> > It happens regardless there is HW RX VLAN stripping enabled or not.
>
> When RX VLAN stripping is enabled we hit the BUG() in the
> vlan_hwaccel_do_receive().:
We hit the same BUG() both when VLAN stripping is disabled.
Thanks,
vlad
>
>
>
>
>
> >
> > Thanks,
> > vlad
> >
> > >
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe netdev"
> in
> > > the body of a message to majordomo@vger.kernel.org
> > > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe netdev" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* email-selected
From: Microsoft @ 2010-10-21 14:45 UTC (permalink / raw)
Your Email Id has won 1,000,000.00 GBP in the British Online Promotion 2010. send your
Names.
Age:
Address.
Occupation:
Tel.
to our claims department :claims.012@hotmail.com
+44 7010 039 919
^ permalink raw reply
* Re: [PATCH v2 9/9] tproxy: use the interface primary IP address as a default value for --on-ip
From: Patrick McHardy @ 2010-10-21 14:48 UTC (permalink / raw)
To: Amos Jeffries; +Cc: KOVACS Krisztian, netdev, netfilter-devel, Balazs Scheidler
In-Reply-To: <4CC04D97.9020105@treenet.co.nz>
Am 21.10.2010 16:26, schrieb Amos Jeffries:
> On 22/10/10 03:21, Patrick McHardy wrote:
>> Also applied, thanks a lot.
>>
>
> Hoooray!! Thanks very, very, very much.
>
> Just one followup question:
> which kernel and iptables release is this now headed for?
These patches will appear in 2.6.37-rc.
^ permalink raw reply
* Re: [PATCH] ibmveth: Increase default copybreak limits to 2k
From: David Miller @ 2010-10-21 14:45 UTC (permalink / raw)
To: rcj; +Cc: netdev
In-Reply-To: <20101021143753.GA5567@linux.vnet.ibm.com>
From: Robert Jennings <rcj@linux.vnet.ibm.com>
Date: Thu, 21 Oct 2010 09:37:53 -0500
> Increase the copybreak limits for rx and tx from 128 bytes
> to 2048 bytes. These limits were added by commits
> 8d86c61ae41d9068fd5e5cc01a4abd53c4fe3ab5 and
> c08cc3ccebd46dce44d13a8ce81d249e687eeb8a to make use of a
> bounce buffer for packets below 128 bytes. This avoids
> tearing down and creating a TCE entry.
>
> Performance testing shows that this default limit can be
> increased from 128 to 2048 for both rx and tx copybreak.
> This resulted in ~10% throughput increase for for packets
> that fit this limit without affecting performance for larger
> packets.
>
> Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
For a default MTU of 1500 this means the copybreak will
never be used.
This makes absolutely no sense, are you doing these tests
with Jumbo frames?
^ permalink raw reply
* [PATCH v2 08/22] rds: stop including asm-generic/bitops/le.h
From: Akinobu Mita @ 2010-10-21 14:41 UTC (permalink / raw)
To: linux-kernel, linux-arch, Arnd Bergmann, Christoph Hellwig,
Andrew Morton
Cc: Akinobu Mita, Andy Grover, rds-devel, David S. Miller, netdev
In-Reply-To: <1287672077-5797-1-git-send-email-akinobu.mita@gmail.com>
No need to include asm-generic/bitops/le.h as all architectures
provide little-endian bit operations now.
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Andy Grover <andy.grover@oracle.com>
Cc: rds-devel@oss.oracle.com
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
---
No change from previous submission
net/rds/cong.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/net/rds/cong.c b/net/rds/cong.c
index c6784d5..15a65f0 100644
--- a/net/rds/cong.c
+++ b/net/rds/cong.c
@@ -34,8 +34,6 @@
#include <linux/types.h>
#include <linux/rbtree.h>
-#include <asm-generic/bitops/le.h>
-
#include "rds.h"
/*
--
1.7.1.231.gd0b16
^ permalink raw reply related
* [PATCH v2 02/22] bitops: rename generic little-endian bitops functions
From: Akinobu Mita @ 2010-10-21 14:40 UTC (permalink / raw)
To: linux-kernel, linux-arch, Arnd Bergmann, Christoph Hellwig,
Andrew Morton
Cc: rds-devel, kvm, Marcelo Tosatti, Akinobu Mita, David S. Miller,
Andy Grover, linux-m68k, netdev, Andreas Schwab, Avi Kivity,
Greg Ungerer, Geert Uytterhoeven, linuxppc-dev,
Hans-Christian Egtvedt, Paul Mackerras
In-Reply-To: <1287672077-5797-1-git-send-email-akinobu.mita@gmail.com>
As a preparation for providing little-endian bitops for all architectures,
This removes generic_ prefix from little-endian bitops function names
in asm-generic/bitops/le.h.
s/generic_find_next_le_bit/find_next_le_bit/
s/generic_find_next_zero_le_bit/find_next_zero_le_bit/
s/generic_find_first_zero_le_bit/find_first_zero_le_bit/
s/generic___test_and_set_le_bit/__test_and_set_le_bit/
s/generic___test_and_clear_le_bit/__test_and_clear_le_bit/
s/generic_test_le_bit/test_le_bit/
s/generic___set_le_bit/__set_le_bit/
s/generic___clear_le_bit/__clear_le_bit/
s/generic_test_and_set_le_bit/test_and_set_le_bit/
s/generic_test_and_clear_le_bit/test_and_clear_le_bit/
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: Andreas Schwab <schwab@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
Cc: Greg Ungerer <gerg@uclinux.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Andy Grover <andy.grover@oracle.com>
Cc: rds-devel@oss.oracle.com
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Cc: Avi Kivity <avi@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: kvm@vger.kernel.org
---
No change from previous submission
arch/avr32/kernel/avr32_ksyms.c | 4 ++--
arch/avr32/lib/findbit.S | 4 ++--
arch/m68k/include/asm/bitops_mm.h | 8 ++++----
arch/m68k/include/asm/bitops_no.h | 2 +-
arch/powerpc/include/asm/bitops.h | 11 ++++++-----
include/asm-generic/bitops/ext2-non-atomic.h | 12 ++++++------
include/asm-generic/bitops/le.h | 26 +++++++++++++-------------
include/asm-generic/bitops/minix-le.h | 10 +++++-----
lib/find_next_bit.c | 9 ++++-----
net/rds/cong.c | 6 +++---
virt/kvm/kvm_main.c | 2 +-
11 files changed, 47 insertions(+), 47 deletions(-)
diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c
index 11e310c..c63b943 100644
--- a/arch/avr32/kernel/avr32_ksyms.c
+++ b/arch/avr32/kernel/avr32_ksyms.c
@@ -58,8 +58,8 @@ EXPORT_SYMBOL(find_first_zero_bit);
EXPORT_SYMBOL(find_next_zero_bit);
EXPORT_SYMBOL(find_first_bit);
EXPORT_SYMBOL(find_next_bit);
-EXPORT_SYMBOL(generic_find_next_le_bit);
-EXPORT_SYMBOL(generic_find_next_zero_le_bit);
+EXPORT_SYMBOL(find_next_le_bit);
+EXPORT_SYMBOL(find_next_zero_le_bit);
/* I/O primitives (lib/io-*.S) */
EXPORT_SYMBOL(__raw_readsb);
diff --git a/arch/avr32/lib/findbit.S b/arch/avr32/lib/findbit.S
index 997b33b..6880d85 100644
--- a/arch/avr32/lib/findbit.S
+++ b/arch/avr32/lib/findbit.S
@@ -123,7 +123,7 @@ ENTRY(find_next_bit)
brgt 1b
retal r11
-ENTRY(generic_find_next_le_bit)
+ENTRY(find_next_le_bit)
lsr r8, r10, 5
sub r9, r11, r10
retle r11
@@ -153,7 +153,7 @@ ENTRY(generic_find_next_le_bit)
brgt 1b
retal r11
-ENTRY(generic_find_next_zero_le_bit)
+ENTRY(find_next_zero_le_bit)
lsr r8, r10, 5
sub r9, r11, r10
retle r11
diff --git a/arch/m68k/include/asm/bitops_mm.h b/arch/m68k/include/asm/bitops_mm.h
index b4ecdaa..f1010ab 100644
--- a/arch/m68k/include/asm/bitops_mm.h
+++ b/arch/m68k/include/asm/bitops_mm.h
@@ -366,9 +366,9 @@ static inline int minix_test_bit(int nr, const void *vaddr)
#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
#define ext2_find_next_zero_bit(addr, size, offset) \
- generic_find_next_zero_le_bit((unsigned long *)addr, size, offset)
+ find_next_zero_le_bit((unsigned long *)addr, size, offset)
#define ext2_find_next_bit(addr, size, offset) \
- generic_find_next_le_bit((unsigned long *)addr, size, offset)
+ find_next_le_bit((unsigned long *)addr, size, offset)
static inline int ext2_test_bit(int nr, const void *vaddr)
{
@@ -398,7 +398,7 @@ static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size)
return (p - addr) * 32 + res;
}
-static inline unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
+static inline unsigned long find_next_zero_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
{
const unsigned long *p = addr + (offset >> 5);
@@ -440,7 +440,7 @@ static inline int ext2_find_first_bit(const void *vaddr, unsigned size)
return (p - addr) * 32 + res;
}
-static inline unsigned long generic_find_next_le_bit(const unsigned long *addr,
+static inline unsigned long find_next_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset)
{
const unsigned long *p = addr + (offset >> 5);
diff --git a/arch/m68k/include/asm/bitops_no.h b/arch/m68k/include/asm/bitops_no.h
index 9d3cbe5..292e1ce 100644
--- a/arch/m68k/include/asm/bitops_no.h
+++ b/arch/m68k/include/asm/bitops_no.h
@@ -325,7 +325,7 @@ found_middle:
}
#define ext2_find_next_bit(addr, size, off) \
- generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
+ find_next_le_bit((unsigned long *)(addr), (size), (off))
#include <asm-generic/bitops/minix.h>
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index 30964ae..b4f3f84 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -294,11 +294,12 @@ static __inline__ int test_le_bit(unsigned long nr,
#define __test_and_clear_le_bit(nr, addr) \
__test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define find_first_zero_le_bit(addr, size) generic_find_next_zero_le_bit((addr), (size), 0)
-unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
+#define find_first_zero_le_bit(addr, size) \
+ find_next_zero_le_bit((addr), (size), 0)
+unsigned long find_next_zero_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
-unsigned long generic_find_next_le_bit(const unsigned long *addr,
+unsigned long find_next_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
/* Bitmap functions for the ext2 filesystem */
@@ -317,10 +318,10 @@ unsigned long generic_find_next_le_bit(const unsigned long *addr,
#define ext2_find_first_zero_bit(addr, size) \
find_first_zero_le_bit((unsigned long*)addr, size)
#define ext2_find_next_zero_bit(addr, size, off) \
- generic_find_next_zero_le_bit((unsigned long*)addr, size, off)
+ find_next_zero_le_bit((unsigned long *)addr, size, off)
#define ext2_find_next_bit(addr, size, off) \
- generic_find_next_le_bit((unsigned long *)addr, size, off)
+ find_next_le_bit((unsigned long *)addr, size, off)
/* Bitmap functions for the minix filesystem. */
#define minix_test_and_set_bit(nr,addr) \
diff --git a/include/asm-generic/bitops/ext2-non-atomic.h b/include/asm-generic/bitops/ext2-non-atomic.h
index 63cf822..9c7bb9a 100644
--- a/include/asm-generic/bitops/ext2-non-atomic.h
+++ b/include/asm-generic/bitops/ext2-non-atomic.h
@@ -4,17 +4,17 @@
#include <asm-generic/bitops/le.h>
#define ext2_set_bit(nr,addr) \
- generic___test_and_set_le_bit((nr),(unsigned long *)(addr))
+ __test_and_set_le_bit((nr), (unsigned long *)(addr))
#define ext2_clear_bit(nr,addr) \
- generic___test_and_clear_le_bit((nr),(unsigned long *)(addr))
+ __test_and_clear_le_bit((nr), (unsigned long *)(addr))
#define ext2_test_bit(nr,addr) \
- generic_test_le_bit((nr),(unsigned long *)(addr))
+ test_le_bit((nr), (unsigned long *)(addr))
#define ext2_find_first_zero_bit(addr, size) \
- generic_find_first_zero_le_bit((unsigned long *)(addr), (size))
+ find_first_zero_le_bit((unsigned long *)(addr), (size))
#define ext2_find_next_zero_bit(addr, size, off) \
- generic_find_next_zero_le_bit((unsigned long *)(addr), (size), (off))
+ find_next_zero_le_bit((unsigned long *)(addr), (size), (off))
#define ext2_find_next_bit(addr, size, off) \
- generic_find_next_le_bit((unsigned long *)(addr), (size), (off))
+ find_next_le_bit((unsigned long *)(addr), (size), (off))
#endif /* _ASM_GENERIC_BITOPS_EXT2_NON_ATOMIC_H_ */
diff --git a/include/asm-generic/bitops/le.h b/include/asm-generic/bitops/le.h
index db2be81..6ad46ce 100644
--- a/include/asm-generic/bitops/le.h
+++ b/include/asm-generic/bitops/le.h
@@ -8,42 +8,42 @@
#define BITOP_LE_SWIZZLE 0
-#define generic_find_next_zero_le_bit(addr, size, offset) \
+#define find_next_zero_le_bit(addr, size, offset) \
find_next_zero_bit(addr, size, offset)
-#define generic_find_next_le_bit(addr, size, offset) \
+#define find_next_le_bit(addr, size, offset) \
find_next_bit(addr, size, offset)
#elif defined(__BIG_ENDIAN)
#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)
-extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
+extern unsigned long find_next_zero_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
-extern unsigned long generic_find_next_le_bit(const unsigned long *addr,
+extern unsigned long find_next_le_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
#else
#error "Please fix <asm/byteorder.h>"
#endif
-#define generic_test_le_bit(nr, addr) \
+#define test_le_bit(nr, addr) \
test_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define generic___set_le_bit(nr, addr) \
+#define __set_le_bit(nr, addr) \
__set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define generic___clear_le_bit(nr, addr) \
+#define __clear_le_bit(nr, addr) \
__clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define generic_test_and_set_le_bit(nr, addr) \
+#define test_and_set_le_bit(nr, addr) \
test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define generic_test_and_clear_le_bit(nr, addr) \
+#define test_and_clear_le_bit(nr, addr) \
test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define generic___test_and_set_le_bit(nr, addr) \
+#define __test_and_set_le_bit(nr, addr) \
__test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define generic___test_and_clear_le_bit(nr, addr) \
+#define __test_and_clear_le_bit(nr, addr) \
__test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
-#define generic_find_first_zero_le_bit(addr, size) \
- generic_find_next_zero_le_bit((addr), (size), 0)
+#define find_first_zero_le_bit(addr, size) \
+ find_next_zero_le_bit((addr), (size), 0)
#endif /* _ASM_GENERIC_BITOPS_LE_H_ */
diff --git a/include/asm-generic/bitops/minix-le.h b/include/asm-generic/bitops/minix-le.h
index 4a981c1..ed0ae09 100644
--- a/include/asm-generic/bitops/minix-le.h
+++ b/include/asm-generic/bitops/minix-le.h
@@ -4,14 +4,14 @@
#include <asm-generic/bitops/le.h>
#define minix_test_and_set_bit(nr,addr) \
- generic___test_and_set_le_bit((nr),(unsigned long *)(addr))
+ __test_and_set_le_bit((nr), (unsigned long *)(addr))
#define minix_set_bit(nr,addr) \
- generic___set_le_bit((nr),(unsigned long *)(addr))
+ __set_le_bit((nr), (unsigned long *)(addr))
#define minix_test_and_clear_bit(nr,addr) \
- generic___test_and_clear_le_bit((nr),(unsigned long *)(addr))
+ __test_and_clear_le_bit((nr), (unsigned long *)(addr))
#define minix_test_bit(nr,addr) \
- generic_test_le_bit((nr),(unsigned long *)(addr))
+ test_le_bit((nr), (unsigned long *)(addr))
#define minix_find_first_zero_bit(addr,size) \
- generic_find_first_zero_le_bit((unsigned long *)(addr),(size))
+ find_first_zero_le_bit((unsigned long *)(addr), (size))
#endif /* _ASM_GENERIC_BITOPS_MINIX_LE_H_ */
diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c
index 24c59de..eb8934b 100644
--- a/lib/find_next_bit.c
+++ b/lib/find_next_bit.c
@@ -185,7 +185,7 @@ static inline unsigned long ext2_swab(const unsigned long y)
#endif
}
-unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, unsigned
+unsigned long find_next_zero_le_bit(const unsigned long *addr, unsigned
long size, unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset);
@@ -226,10 +226,9 @@ found_middle:
found_middle_swap:
return result + ffz(ext2_swab(tmp));
}
+EXPORT_SYMBOL(find_next_zero_le_bit);
-EXPORT_SYMBOL(generic_find_next_zero_le_bit);
-
-unsigned long generic_find_next_le_bit(const unsigned long *addr, unsigned
+unsigned long find_next_le_bit(const unsigned long *addr, unsigned
long size, unsigned long offset)
{
const unsigned long *p = addr + BITOP_WORD(offset);
@@ -271,5 +270,5 @@ found_middle:
found_middle_swap:
return result + __ffs(ext2_swab(tmp));
}
-EXPORT_SYMBOL(generic_find_next_le_bit);
+EXPORT_SYMBOL(find_next_le_bit);
#endif /* __BIG_ENDIAN */
diff --git a/net/rds/cong.c b/net/rds/cong.c
index 0871a29..c6784d5 100644
--- a/net/rds/cong.c
+++ b/net/rds/cong.c
@@ -285,7 +285,7 @@ void rds_cong_set_bit(struct rds_cong_map *map, __be16 port)
i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS;
off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS;
- generic___set_le_bit(off, (void *)map->m_page_addrs[i]);
+ __set_le_bit(off, (void *)map->m_page_addrs[i]);
}
void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port)
@@ -299,7 +299,7 @@ void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port)
i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS;
off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS;
- generic___clear_le_bit(off, (void *)map->m_page_addrs[i]);
+ __clear_le_bit(off, (void *)map->m_page_addrs[i]);
}
static int rds_cong_test_bit(struct rds_cong_map *map, __be16 port)
@@ -310,7 +310,7 @@ static int rds_cong_test_bit(struct rds_cong_map *map, __be16 port)
i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS;
off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS;
- return generic_test_le_bit(off, (void *)map->m_page_addrs[i]);
+ return test_le_bit(off, (void *)map->m_page_addrs[i]);
}
void rds_cong_add_socket(struct rds_sock *rs)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 5186e72..2d9927c 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1208,7 +1208,7 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
if (memslot && memslot->dirty_bitmap) {
unsigned long rel_gfn = gfn - memslot->base_gfn;
- generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
+ __set_le_bit(rel_gfn, memslot->dirty_bitmap);
}
}
--
1.7.1.231.gd0b16
^ permalink raw reply related
* [PATCH] ibmveth: Increase default copybreak limits to 2k
From: Robert Jennings @ 2010-10-21 14:37 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Increase the copybreak limits for rx and tx from 128 bytes
to 2048 bytes. These limits were added by commits
8d86c61ae41d9068fd5e5cc01a4abd53c4fe3ab5 and
c08cc3ccebd46dce44d13a8ce81d249e687eeb8a to make use of a
bounce buffer for packets below 128 bytes. This avoids
tearing down and creating a TCE entry.
Performance testing shows that this default limit can be
increased from 128 to 2048 for both rx and tx copybreak.
This resulted in ~10% throughput increase for for packets
that fit this limit without affecting performance for larger
packets.
Signed-off-by: Robert Jennings <rcj@linux.vnet.ibm.com>
---
drivers/net/ibmveth.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index c454b45..20b7a98 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -65,12 +65,12 @@ MODULE_DESCRIPTION("IBM Power Virtual Ethernet Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(ibmveth_driver_version);
-static unsigned int tx_copybreak __read_mostly = 128;
+static unsigned int tx_copybreak __read_mostly = 2048;
module_param(tx_copybreak, uint, 0644);
MODULE_PARM_DESC(tx_copybreak,
"Maximum size of packet that is copied to a new buffer on transmit");
-static unsigned int rx_copybreak __read_mostly = 128;
+static unsigned int rx_copybreak __read_mostly = 2048;
module_param(rx_copybreak, uint, 0644);
MODULE_PARM_DESC(rx_copybreak,
"Maximum size of packet that is copied to a new buffer on receive");
--
1.7.0.4
^ permalink raw reply related
* Re: [RFC PATCH 5/9] ipvs network name space aware
From: Simon Horman @ 2010-10-21 14:34 UTC (permalink / raw)
To: Hans Schillstrom
Cc: Eric Dumazet, lvs-devel@vger.kernel.org, netdev@vger.kernel.org,
netfilter-devel@vger.kernel.org, ja@ssi.bg, wensong@linux-vs.org,
daniel.lezcano@free.fr
In-Reply-To: <201010211349.25921.hans.schillstrom@ericsson.com>
On Thu, Oct 21, 2010 at 01:49:25PM +0200, Hans Schillstrom wrote:
> On Thursday 21 October 2010 13:26:54 Eric Dumazet wrote:
> > Le jeudi 21 octobre 2010 à 13:16 +0200, Simon Horman a écrit :
> >
> > > > @@ -2680,10 +2664,15 @@ static int ip_vs_genl_dump_services(struct sk_buff *skb,
> > > > int idx = 0, i;
> > > > int start = cb->args[0];
> > > > struct ip_vs_service *svc;
> > > > -
> > > > + struct net *net = skb->sk->sk_net;
> > >
> > > skb->sk->sk_net needs CONFIG_NS_NET.
> > > Is your plan for IPVS to unconditionally depend on CONFIG_NS_NET?
> > > It would be nice to avoid that, but I fear it will be too messy.
> > >
> >
> >
> > struct net *net = sock_net(skb->sk);
> >
> > is your friend ;)
> >
> >
> Tanks Eric,
>
> Simon,
> do forget about my last mail....
Done :-)
^ permalink raw reply
* Re: [GIT PULL nf-next-2.6] ipvs + nf_net
From: Patrick McHardy @ 2010-10-21 14:27 UTC (permalink / raw)
To: Simon Horman
Cc: netfilter-devel, lvs-devel, netdev, Julian Anastasov,
Hans Schillstrom
In-Reply-To: <20101021142446.GA19085@verge.net.au>
Am 21.10.2010 16:24, schrieb Simon Horman:
> git://git.kernel.org/pub/scm/linux/kernel/git/horms/lvs-test-2.6.git for-patrick
Pulled, thanks Simon.
^ permalink raw reply
* Re: [PATCH v2 9/9] tproxy: use the interface primary IP address as a default value for --on-ip
From: Amos Jeffries @ 2010-10-21 14:26 UTC (permalink / raw)
To: Patrick McHardy
Cc: KOVACS Krisztian, netdev, netfilter-devel, Balazs Scheidler
In-Reply-To: <4CC04C81.9080504@trash.net>
On 22/10/10 03:21, Patrick McHardy wrote:
> Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
>> From: Balazs Scheidler<bazsi@balabit.hu>
>>
>> The REDIRECT target and the older TProxy versions used the primary address
>> of the incoming interface as the default value of the --on-ip parameter.
>> This was unintentionally changed during the initial TProxy submission and
>> caused confusion among users.
>>
>> Since IPv6 has no notion of primary address, we just select the first address
>> on the list: this way the socket lookup finds wildcard bound sockets
>> properly and we cannot really do better without the user telling us the
>> IPv6 address of the proxy.
>>
>> This is implemented for both IPv4 and IPv6.
>
>
> Also applied, thanks a lot.
>
Hoooray!! Thanks very, very, very much.
Just one followup question:
which kernel and iptables release is this now headed for?
AYJ
^ permalink raw reply
* [GIT PULL nf-next-2.6] ipvs + nf_net
From: Simon Horman @ 2010-10-21 14:24 UTC (permalink / raw)
To: netfilter-devel, lvs-devel, netdev
Cc: Patrick McHardy, Julian Anastasov, Hans Schillstrom
Hi Patrick,
please consider pulling the following. The changes
are the 12 IPVS patch series that Julian recently posted
as well as his ICMP translation patch.
The following changes since commit d86bef73b4a24e59e7c1f896a72bbf38430ac2c6:
Fixed race condition at ip_vs.ko module init. (2010-10-19 17:13:16 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/horms/lvs-test-2.6.git for-patrick
Julian Anastasov (13):
ipvs: fix CHECKSUM_PARTIAL for TCP, UDP
ipvs: optimize checksums for apps
ipvs: switch to notrack mode
ipvs: do not schedule conns from real servers
ipvs: stop ICMP from FORWARD to local
ipvs: fix CHECKSUM_PARTIAL for TUN method
ipvs: create ip_vs_defrag_user
ipvs: move ip_route_me_harder for ICMP
ipvs: changes for local real server
ipvs: changes for local client
ipvs: inherit forwarding method in backup
ipvs: provide address family for debugging
nf_nat: restrict ICMP translation for embedded header
include/net/ip_vs.h | 53 +++-
net/ipv4/netfilter/nf_nat_core.c | 29 +-
net/netfilter/ipvs/ip_vs_conn.c | 2 +
net/netfilter/ipvs/ip_vs_core.c | 586 ++++++++++++++++++++++---------
net/netfilter/ipvs/ip_vs_ctl.c | 18 +-
net/netfilter/ipvs/ip_vs_ftp.c | 7 +-
net/netfilter/ipvs/ip_vs_proto.c | 8 +-
net/netfilter/ipvs/ip_vs_proto_ah_esp.c | 52 +---
net/netfilter/ipvs/ip_vs_proto_sctp.c | 8 +-
net/netfilter/ipvs/ip_vs_proto_tcp.c | 52 ++-
net/netfilter/ipvs/ip_vs_proto_udp.c | 51 ++-
net/netfilter/ipvs/ip_vs_xmit.c | 503 +++++++++++++++++++++------
12 files changed, 959 insertions(+), 410 deletions(-)
^ permalink raw reply
* Re: [PATCH v2 9/9] tproxy: use the interface primary IP address as a default value for --on-ip
From: Patrick McHardy @ 2010-10-21 14:21 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <20101021104710.5192.65152.stgit@este.odu>
Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
> From: Balazs Scheidler <bazsi@balabit.hu>
>
> The REDIRECT target and the older TProxy versions used the primary address
> of the incoming interface as the default value of the --on-ip parameter.
> This was unintentionally changed during the initial TProxy submission and
> caused confusion among users.
>
> Since IPv6 has no notion of primary address, we just select the first address
> on the list: this way the socket lookup finds wildcard bound sockets
> properly and we cannot really do better without the user telling us the
> IPv6 address of the proxy.
>
> This is implemented for both IPv4 and IPv6.
Also applied, thanks a lot.
^ permalink raw reply
* Re: [PATCH v2 8/9] tproxy: added IPv6 support to the socket match
From: Patrick McHardy @ 2010-10-21 14:20 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <20101021104709.5192.41764.stgit@este.odu>
Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
> The ICMP extraction bits were contributed by Harry Mason.
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 1/3] cxgb3: function namespace cleanup
From: David Miller @ 2010-10-21 14:19 UTC (permalink / raw)
To: divy; +Cc: shemminger, leedom, dm, netdev
In-Reply-To: <4CBCF10C.4010900@chelsio.com>
From: Divy Le Ray <divy@chelsio.com>
Date: Mon, 18 Oct 2010 18:14:52 -0700
> On 10/15/2010 03:43 PM, Stephen Hemminger wrote:
>> Make local functions static. Remove functions that are
>> defined and never used. Compile tested only.
>>
>> Signed-off-by: Stephen Hemminger<shemminger@vyatta.com>
>
> Acked-by: Divy Le Ray <divy@chelsio.com>
Applied.
^ permalink raw reply
* Re: [PATCH v2 7/9] tproxy: added IPv6 support to the TPROXY target
From: Patrick McHardy @ 2010-10-21 14:17 UTC (permalink / raw)
To: KOVACS Krisztian; +Cc: netdev, netfilter-devel, Balazs Scheidler, David Miller
In-Reply-To: <20101021104709.5192.99755.stgit@este.odu>
Am 21.10.2010 12:47, schrieb KOVACS Krisztian:
> This requires a new revision as the old target structure was
> IPv4 specific.
Applied, thanks.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox