* [PATCH 35/36] netfilter: conntrack: use a single nat bysource table for all namespaces
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
We already include netns address in the hash, so we only need to use
net_eq in find_appropriate_src and can then put all entries into
same table.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netns/conntrack.h | 4 ----
net/netfilter/nf_nat_core.c | 33 +++++++++++++++++----------------
2 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index 2811ddc..1e751bf 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -103,9 +103,5 @@ struct netns_ct {
unsigned int labels_used;
u8 label_words;
#endif
-#ifdef CONFIG_NF_NAT_NEEDED
- struct hlist_head *nat_bysource;
- unsigned int nat_htable_size;
-#endif
};
#endif
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 069912c..6877a39 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -37,6 +37,9 @@ static const struct nf_nat_l3proto __rcu *nf_nat_l3protos[NFPROTO_NUMPROTO]
__read_mostly;
static const struct nf_nat_l4proto __rcu **nf_nat_l4protos[NFPROTO_NUMPROTO]
__read_mostly;
+
+static struct hlist_head *nf_nat_bysource __read_mostly;
+static unsigned int nf_nat_htable_size __read_mostly;
static unsigned int nf_nat_hash_rnd __read_mostly;
inline const struct nf_nat_l3proto *
@@ -128,7 +131,7 @@ hash_by_src(const struct net *n, const struct nf_conntrack_tuple *tuple)
hash = jhash2((u32 *)&tuple->src, sizeof(tuple->src) / sizeof(u32),
tuple->dst.protonum ^ nf_nat_hash_rnd ^ net_hash_mix(n));
- return reciprocal_scale(hash, n->ct.nat_htable_size);
+ return reciprocal_scale(hash, nf_nat_htable_size);
}
/* Is this tuple already taken? (not by us) */
@@ -198,9 +201,10 @@ find_appropriate_src(struct net *net,
const struct nf_conn_nat *nat;
const struct nf_conn *ct;
- hlist_for_each_entry_rcu(nat, &net->ct.nat_bysource[h], bysource) {
+ hlist_for_each_entry_rcu(nat, &nf_nat_bysource[h], bysource) {
ct = nat->ct;
if (same_src(ct, tuple) &&
+ net_eq(net, nf_ct_net(ct)) &&
nf_ct_zone_equal(ct, zone, IP_CT_DIR_ORIGINAL)) {
/* Copy source part from reply tuple. */
nf_ct_invert_tuplepr(result,
@@ -433,7 +437,7 @@ nf_nat_setup_info(struct nf_conn *ct,
nat = nfct_nat(ct);
nat->ct = ct;
hlist_add_head_rcu(&nat->bysource,
- &net->ct.nat_bysource[srchash]);
+ &nf_nat_bysource[srchash]);
spin_unlock_bh(&nf_nat_lock);
}
@@ -821,27 +825,14 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct,
}
#endif
-static int __net_init nf_nat_net_init(struct net *net)
-{
- /* Leave them the same for the moment. */
- net->ct.nat_htable_size = nf_conntrack_htable_size;
- net->ct.nat_bysource = nf_ct_alloc_hashtable(&net->ct.nat_htable_size, 0);
- if (!net->ct.nat_bysource)
- return -ENOMEM;
- return 0;
-}
-
static void __net_exit nf_nat_net_exit(struct net *net)
{
struct nf_nat_proto_clean clean = {};
nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean, 0, 0);
- synchronize_rcu();
- nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size);
}
static struct pernet_operations nf_nat_net_ops = {
- .init = nf_nat_net_init,
.exit = nf_nat_net_exit,
};
@@ -854,8 +845,16 @@ static int __init nf_nat_init(void)
{
int ret;
+ /* Leave them the same for the moment. */
+ nf_nat_htable_size = nf_conntrack_htable_size;
+
+ nf_nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, 0);
+ if (!nf_nat_bysource)
+ return -ENOMEM;
+
ret = nf_ct_extend_register(&nat_extend);
if (ret < 0) {
+ nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size);
printk(KERN_ERR "nf_nat_core: Unable to register extension\n");
return ret;
}
@@ -879,6 +878,7 @@ static int __init nf_nat_init(void)
return 0;
cleanup_extend:
+ nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size);
nf_ct_extend_unregister(&nat_extend);
return ret;
}
@@ -897,6 +897,7 @@ static void __exit nf_nat_cleanup(void)
for (i = 0; i < NFPROTO_NUMPROTO; i++)
kfree(nf_nat_l4protos[i]);
synchronize_net();
+ nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size);
}
MODULE_LICENSE("GPL");
--
2.1.4
^ permalink raw reply related
* [PATCH 34/36] netfilter: conntrack: make netns address part of nat bysrc hash
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
Will be needed soon when we place all in the same hash table.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_nat_core.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index d74e716..069912c 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -118,7 +118,7 @@ EXPORT_SYMBOL(nf_xfrm_me_harder);
/* We keep an extra hash for each conntrack, for fast searching. */
static inline unsigned int
-hash_by_src(const struct net *net, const struct nf_conntrack_tuple *tuple)
+hash_by_src(const struct net *n, const struct nf_conntrack_tuple *tuple)
{
unsigned int hash;
@@ -126,9 +126,9 @@ hash_by_src(const struct net *net, const struct nf_conntrack_tuple *tuple)
/* Original src, to ensure we map it consistently if poss. */
hash = jhash2((u32 *)&tuple->src, sizeof(tuple->src) / sizeof(u32),
- tuple->dst.protonum ^ nf_nat_hash_rnd);
+ tuple->dst.protonum ^ nf_nat_hash_rnd ^ net_hash_mix(n));
- return reciprocal_scale(hash, net->ct.nat_htable_size);
+ return reciprocal_scale(hash, n->ct.nat_htable_size);
}
/* Is this tuple already taken? (not by us) */
--
2.1.4
^ permalink raw reply related
* [PATCH 30/36] ipvs: make drop_entry protection effective for SIP-pe
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Marco Angaroni <marcoangaroni@gmail.com>
DoS protection policy that deletes connections to avoid out of memory is
currently not effective for SIP-pe plus OPS-mode for two reasons:
1) connection templates (holding SIP call-id) are always skipped in
ip_vs_random_dropentry()
2) in_pkts counter (used by drop_entry algorithm) is not incremented
for connection templates
This patch addresses such problems with the following changes:
a) connection templates associated (via their dest) to virtual-services
configured in OPS mode are included in ip_vs_random_dropentry()
monitoring. This applies to SIP-pe over UDP (which requires OPS mode),
but is more general principle: when OPS is controlled by templates
memory can be used only by templates themselves, since OPS conns are
deleted after packet is forwarded.
b) OPS connections, if controlled by a template, cause increment of
in_pkts counter of their template. This is already happening but only
in case director is in master-slave mode (see ip_vs_sync_conn()).
Signed-off-by: Marco Angaroni <marcoangaroni@gmail.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
net/netfilter/ipvs/ip_vs_conn.c | 22 +++++++++++++++++++---
net/netfilter/ipvs/ip_vs_core.c | 8 +++++++-
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 292365f..2cb3c62 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -1261,6 +1261,16 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
return 1;
}
+static inline bool ip_vs_conn_ops_mode(struct ip_vs_conn *cp)
+{
+ struct ip_vs_service *svc;
+
+ if (!cp->dest)
+ return false;
+ svc = rcu_dereference(cp->dest->svc);
+ return svc && (svc->flags & IP_VS_SVC_F_ONEPACKET);
+}
+
/* Called from keventd and must protect itself from softirqs */
void ip_vs_random_dropentry(struct netns_ipvs *ipvs)
{
@@ -1275,11 +1285,16 @@ void ip_vs_random_dropentry(struct netns_ipvs *ipvs)
unsigned int hash = prandom_u32() & ip_vs_conn_tab_mask;
hlist_for_each_entry_rcu(cp, &ip_vs_conn_tab[hash], c_list) {
- if (cp->flags & IP_VS_CONN_F_TEMPLATE)
- /* connection template */
- continue;
if (cp->ipvs != ipvs)
continue;
+ if (cp->flags & IP_VS_CONN_F_TEMPLATE) {
+ if (atomic_read(&cp->n_control) ||
+ !ip_vs_conn_ops_mode(cp))
+ continue;
+ else
+ /* connection template of OPS */
+ goto try_drop;
+ }
if (cp->protocol == IPPROTO_TCP) {
switch(cp->state) {
case IP_VS_TCP_S_SYN_RECV:
@@ -1307,6 +1322,7 @@ void ip_vs_random_dropentry(struct netns_ipvs *ipvs)
continue;
}
} else {
+try_drop:
if (!todrop_entry(cp))
continue;
}
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index f3bac2e..1207f20 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -612,7 +612,10 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
ret = cp->packet_xmit(skb, cp, pd->pp, iph);
/* do not touch skb anymore */
- atomic_inc(&cp->in_pkts);
+ if ((cp->flags & IP_VS_CONN_F_ONE_PACKET) && cp->control)
+ atomic_inc(&cp->control->in_pkts);
+ else
+ atomic_inc(&cp->in_pkts);
ip_vs_conn_put(cp);
return ret;
}
@@ -1991,6 +1994,9 @@ ip_vs_in(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int
if (ipvs->sync_state & IP_VS_STATE_MASTER)
ip_vs_sync_conn(ipvs, cp, pkts);
+ else if ((cp->flags & IP_VS_CONN_F_ONE_PACKET) && cp->control)
+ /* increment is done inside ip_vs_sync_conn too */
+ atomic_inc(&cp->control->in_pkts);
ip_vs_conn_put(cp);
return ret;
--
2.1.4
^ permalink raw reply related
* [PATCH 28/36] netfilter: x_tables: get rid of old and inconsistent debugging
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
The dprintf() and duprintf() functions are enabled at compile time,
these days we have better runtime debugging through pr_debug() and
static keys.
On top of this, this debugging is so old that I don't expect anyone
using this anymore, so let's get rid of this.
IP_NF_ASSERT() is still left in place, although this needs that
NETFILTER_DEBUG is enabled, I think these assertions provide useful
context information when reading the code.
Note that ARP_NF_ASSERT() has been removed as there is no user of
this.
Kill also DEBUG_ALLOW_ALL and a couple of pr_error() and pr_debug()
spots that are inconsistently placed in the code.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/netfilter/arp_tables.c | 217 ++++++-----------------------------
net/ipv4/netfilter/ip_tables.c | 244 +++++++---------------------------------
net/ipv6/netfilter/ip6_tables.c | 229 +++++++------------------------------
3 files changed, 117 insertions(+), 573 deletions(-)
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 3355ed7..2033f92 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -34,27 +34,6 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
MODULE_DESCRIPTION("arptables core");
-/*#define DEBUG_ARP_TABLES*/
-/*#define DEBUG_ARP_TABLES_USER*/
-
-#ifdef DEBUG_ARP_TABLES
-#define dprintf(format, args...) pr_debug(format, ## args)
-#else
-#define dprintf(format, args...)
-#endif
-
-#ifdef DEBUG_ARP_TABLES_USER
-#define duprintf(format, args...) pr_debug(format, ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
-#ifdef CONFIG_NETFILTER_DEBUG
-#define ARP_NF_ASSERT(x) WARN_ON(!(x))
-#else
-#define ARP_NF_ASSERT(x)
-#endif
-
void *arpt_alloc_initial_table(const struct xt_table *info)
{
return xt_alloc_initial_table(arpt, ARPT);
@@ -113,36 +92,20 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
#define FWINV(bool, invflg) ((bool) ^ !!(arpinfo->invflags & (invflg)))
if (FWINV((arphdr->ar_op & arpinfo->arpop_mask) != arpinfo->arpop,
- ARPT_INV_ARPOP)) {
- dprintf("ARP operation field mismatch.\n");
- dprintf("ar_op: %04x info->arpop: %04x info->arpop_mask: %04x\n",
- arphdr->ar_op, arpinfo->arpop, arpinfo->arpop_mask);
+ ARPT_INV_ARPOP))
return 0;
- }
if (FWINV((arphdr->ar_hrd & arpinfo->arhrd_mask) != arpinfo->arhrd,
- ARPT_INV_ARPHRD)) {
- dprintf("ARP hardware address format mismatch.\n");
- dprintf("ar_hrd: %04x info->arhrd: %04x info->arhrd_mask: %04x\n",
- arphdr->ar_hrd, arpinfo->arhrd, arpinfo->arhrd_mask);
+ ARPT_INV_ARPHRD))
return 0;
- }
if (FWINV((arphdr->ar_pro & arpinfo->arpro_mask) != arpinfo->arpro,
- ARPT_INV_ARPPRO)) {
- dprintf("ARP protocol address format mismatch.\n");
- dprintf("ar_pro: %04x info->arpro: %04x info->arpro_mask: %04x\n",
- arphdr->ar_pro, arpinfo->arpro, arpinfo->arpro_mask);
+ ARPT_INV_ARPPRO))
return 0;
- }
if (FWINV((arphdr->ar_hln & arpinfo->arhln_mask) != arpinfo->arhln,
- ARPT_INV_ARPHLN)) {
- dprintf("ARP hardware address length mismatch.\n");
- dprintf("ar_hln: %02x info->arhln: %02x info->arhln_mask: %02x\n",
- arphdr->ar_hln, arpinfo->arhln, arpinfo->arhln_mask);
+ ARPT_INV_ARPHLN))
return 0;
- }
src_devaddr = arpptr;
arpptr += dev->addr_len;
@@ -155,49 +118,25 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
if (FWINV(arp_devaddr_compare(&arpinfo->src_devaddr, src_devaddr, dev->addr_len),
ARPT_INV_SRCDEVADDR) ||
FWINV(arp_devaddr_compare(&arpinfo->tgt_devaddr, tgt_devaddr, dev->addr_len),
- ARPT_INV_TGTDEVADDR)) {
- dprintf("Source or target device address mismatch.\n");
-
+ ARPT_INV_TGTDEVADDR))
return 0;
- }
if (FWINV((src_ipaddr & arpinfo->smsk.s_addr) != arpinfo->src.s_addr,
ARPT_INV_SRCIP) ||
FWINV(((tgt_ipaddr & arpinfo->tmsk.s_addr) != arpinfo->tgt.s_addr),
- ARPT_INV_TGTIP)) {
- dprintf("Source or target IP address mismatch.\n");
-
- dprintf("SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n",
- &src_ipaddr,
- &arpinfo->smsk.s_addr,
- &arpinfo->src.s_addr,
- arpinfo->invflags & ARPT_INV_SRCIP ? " (INV)" : "");
- dprintf("TGT: %pI4 Mask: %pI4 Target: %pI4.%s\n",
- &tgt_ipaddr,
- &arpinfo->tmsk.s_addr,
- &arpinfo->tgt.s_addr,
- arpinfo->invflags & ARPT_INV_TGTIP ? " (INV)" : "");
+ ARPT_INV_TGTIP))
return 0;
- }
/* Look for ifname matches. */
ret = ifname_compare(indev, arpinfo->iniface, arpinfo->iniface_mask);
- if (FWINV(ret != 0, ARPT_INV_VIA_IN)) {
- dprintf("VIA in mismatch (%s vs %s).%s\n",
- indev, arpinfo->iniface,
- arpinfo->invflags & ARPT_INV_VIA_IN ? " (INV)" : "");
+ if (FWINV(ret != 0, ARPT_INV_VIA_IN))
return 0;
- }
ret = ifname_compare(outdev, arpinfo->outiface, arpinfo->outiface_mask);
- if (FWINV(ret != 0, ARPT_INV_VIA_OUT)) {
- dprintf("VIA out mismatch (%s vs %s).%s\n",
- outdev, arpinfo->outiface,
- arpinfo->invflags & ARPT_INV_VIA_OUT ? " (INV)" : "");
+ if (FWINV(ret != 0, ARPT_INV_VIA_OUT))
return 0;
- }
return 1;
#undef FWINV
@@ -205,16 +144,10 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
static inline int arp_checkentry(const struct arpt_arp *arp)
{
- if (arp->flags & ~ARPT_F_MASK) {
- duprintf("Unknown flag bits set: %08X\n",
- arp->flags & ~ARPT_F_MASK);
+ if (arp->flags & ~ARPT_F_MASK)
return 0;
- }
- if (arp->invflags & ~ARPT_INV_MASK) {
- duprintf("Unknown invflag bits set: %08X\n",
- arp->invflags & ~ARPT_INV_MASK);
+ if (arp->invflags & ~ARPT_INV_MASK)
return 0;
- }
return 1;
}
@@ -406,11 +339,9 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
= (void *)arpt_get_target_c(e);
int visited = e->comefrom & (1 << hook);
- if (e->comefrom & (1 << NF_ARP_NUMHOOKS)) {
- pr_notice("arptables: loop hook %u pos %u %08X.\n",
- hook, pos, e->comefrom);
+ if (e->comefrom & (1 << NF_ARP_NUMHOOKS))
return 0;
- }
+
e->comefrom
|= ((1 << hook) | (1 << NF_ARP_NUMHOOKS));
@@ -423,12 +354,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
if ((strcmp(t->target.u.user.name,
XT_STANDARD_TARGET) == 0) &&
- t->verdict < -NF_MAX_VERDICT - 1) {
- duprintf("mark_source_chains: bad "
- "negative verdict (%i)\n",
- t->verdict);
+ t->verdict < -NF_MAX_VERDICT - 1)
return 0;
- }
/* Return: backtrack through the last
* big jump.
@@ -462,8 +389,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
XT_STANDARD_TARGET) == 0 &&
newpos >= 0) {
/* This a jump; chase it. */
- duprintf("Jump rule %u -> %u\n",
- pos, newpos);
e = (struct arpt_entry *)
(entry0 + newpos);
if (!find_jump_target(newinfo, e))
@@ -480,8 +405,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
pos = newpos;
}
}
-next:
- duprintf("Finished chain %u\n", hook);
+next: ;
}
return 1;
}
@@ -489,7 +413,6 @@ next:
static inline int check_target(struct arpt_entry *e, const char *name)
{
struct xt_entry_target *t = arpt_get_target(e);
- int ret;
struct xt_tgchk_param par = {
.table = name,
.entryinfo = e,
@@ -499,13 +422,7 @@ static inline int check_target(struct arpt_entry *e, const char *name)
.family = NFPROTO_ARP,
};
- ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
- if (ret < 0) {
- duprintf("arp_tables: check failed for `%s'.\n",
- t->u.kernel.target->name);
- return ret;
- }
- return 0;
+ return xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
}
static inline int
@@ -525,7 +442,6 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
t->u.user.revision);
if (IS_ERR(target)) {
- duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
ret = PTR_ERR(target);
goto out;
}
@@ -571,17 +487,12 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 ||
(unsigned char *)e + sizeof(struct arpt_entry) >= limit ||
- (unsigned char *)e + e->next_offset > limit) {
- duprintf("Bad offset %p\n", e);
+ (unsigned char *)e + e->next_offset > limit)
return -EINVAL;
- }
if (e->next_offset
- < sizeof(struct arpt_entry) + sizeof(struct xt_entry_target)) {
- duprintf("checking: element %p size %u\n",
- e, e->next_offset);
+ < sizeof(struct arpt_entry) + sizeof(struct xt_entry_target))
return -EINVAL;
- }
if (!arp_checkentry(&e->arp))
return -EINVAL;
@@ -598,12 +509,9 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
if ((unsigned char *)e - base == hook_entries[h])
newinfo->hook_entry[h] = hook_entries[h];
if ((unsigned char *)e - base == underflows[h]) {
- if (!check_underflow(e)) {
- pr_debug("Underflows must be unconditional and "
- "use the STANDARD target with "
- "ACCEPT/DROP\n");
+ if (!check_underflow(e))
return -EINVAL;
- }
+
newinfo->underflow[h] = underflows[h];
}
}
@@ -648,7 +556,6 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
newinfo->underflow[i] = 0xFFFFFFFF;
}
- duprintf("translate_table: size %u\n", newinfo->size);
i = 0;
/* Walk through entries, checking offsets. */
@@ -665,31 +572,21 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
XT_ERROR_TARGET) == 0)
++newinfo->stacksize;
}
- duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
if (ret != 0)
return ret;
- if (i != repl->num_entries) {
- duprintf("translate_table: %u not %u entries\n",
- i, repl->num_entries);
+ if (i != repl->num_entries)
return -EINVAL;
- }
/* Check hooks all assigned */
for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
/* Only hooks which are valid */
if (!(repl->valid_hooks & (1 << i)))
continue;
- if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
- duprintf("Invalid hook entry %u %u\n",
- i, repl->hook_entry[i]);
+ if (newinfo->hook_entry[i] == 0xFFFFFFFF)
return -EINVAL;
- }
- if (newinfo->underflow[i] == 0xFFFFFFFF) {
- duprintf("Invalid underflow %u %u\n",
- i, repl->underflow[i]);
+ if (newinfo->underflow[i] == 0xFFFFFFFF)
return -EINVAL;
- }
}
if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
@@ -897,11 +794,8 @@ static int get_info(struct net *net, void __user *user,
struct xt_table *t;
int ret;
- if (*len != sizeof(struct arpt_getinfo)) {
- duprintf("length %u != %Zu\n", *len,
- sizeof(struct arpt_getinfo));
+ if (*len != sizeof(struct arpt_getinfo))
return -EINVAL;
- }
if (copy_from_user(name, user, sizeof(name)) != 0)
return -EFAULT;
@@ -957,33 +851,25 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
struct arpt_get_entries get;
struct xt_table *t;
- if (*len < sizeof(get)) {
- duprintf("get_entries: %u < %Zu\n", *len, sizeof(get));
+ if (*len < sizeof(get))
return -EINVAL;
- }
if (copy_from_user(&get, uptr, sizeof(get)) != 0)
return -EFAULT;
- if (*len != sizeof(struct arpt_get_entries) + get.size) {
- duprintf("get_entries: %u != %Zu\n", *len,
- sizeof(struct arpt_get_entries) + get.size);
+ if (*len != sizeof(struct arpt_get_entries) + get.size)
return -EINVAL;
- }
+
get.name[sizeof(get.name) - 1] = '\0';
t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
if (!IS_ERR_OR_NULL(t)) {
const struct xt_table_info *private = t->private;
- duprintf("t->private->number = %u\n",
- private->number);
if (get.size == private->size)
ret = copy_entries_to_user(private->size,
t, uptr->entrytable);
- else {
- duprintf("get_entries: I've got %u not %u!\n",
- private->size, get.size);
+ else
ret = -EAGAIN;
- }
+
module_put(t->me);
xt_table_unlock(t);
} else
@@ -1021,8 +907,6 @@ static int __do_replace(struct net *net, const char *name,
/* You lied! */
if (valid_hooks != t->valid_hooks) {
- duprintf("Valid hook crap: %08X vs %08X\n",
- valid_hooks, t->valid_hooks);
ret = -EINVAL;
goto put_module;
}
@@ -1032,8 +916,6 @@ static int __do_replace(struct net *net, const char *name,
goto put_module;
/* Update module usage count based on number of rules */
- duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
- oldinfo->number, oldinfo->initial_entries, newinfo->number);
if ((oldinfo->number > oldinfo->initial_entries) ||
(newinfo->number <= oldinfo->initial_entries))
module_put(t->me);
@@ -1103,8 +985,6 @@ static int do_replace(struct net *net, const void __user *user,
if (ret != 0)
goto free_newinfo;
- duprintf("arp_tables: Translated table\n");
-
ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, tmp.counters);
if (ret)
@@ -1202,20 +1082,14 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
unsigned int entry_offset;
int ret, off;
- duprintf("check_compat_entry_size_and_hooks %p\n", e);
if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 ||
(unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit ||
- (unsigned char *)e + e->next_offset > limit) {
- duprintf("Bad offset %p, limit = %p\n", e, limit);
+ (unsigned char *)e + e->next_offset > limit)
return -EINVAL;
- }
if (e->next_offset < sizeof(struct compat_arpt_entry) +
- sizeof(struct compat_xt_entry_target)) {
- duprintf("checking: element %p size %u\n",
- e, e->next_offset);
+ sizeof(struct compat_xt_entry_target))
return -EINVAL;
- }
if (!arp_checkentry(&e->arp))
return -EINVAL;
@@ -1232,8 +1106,6 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
t->u.user.revision);
if (IS_ERR(target)) {
- duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
- t->u.user.name);
ret = PTR_ERR(target);
goto out;
}
@@ -1303,7 +1175,6 @@ static int translate_compat_table(struct xt_table_info **pinfo,
size = compatr->size;
info->number = compatr->num_entries;
- duprintf("translate_compat_table: size %u\n", info->size);
j = 0;
xt_compat_lock(NFPROTO_ARP);
xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries);
@@ -1318,11 +1189,8 @@ static int translate_compat_table(struct xt_table_info **pinfo,
}
ret = -EINVAL;
- if (j != compatr->num_entries) {
- duprintf("translate_compat_table: %u not %u entries\n",
- j, compatr->num_entries);
+ if (j != compatr->num_entries)
goto out_unlock;
- }
ret = -ENOMEM;
newinfo = xt_alloc_table_info(size);
@@ -1413,8 +1281,6 @@ static int compat_do_replace(struct net *net, void __user *user,
if (ret != 0)
goto free_newinfo;
- duprintf("compat_do_replace: Translated table\n");
-
ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, compat_ptr(tmp.counters));
if (ret)
@@ -1447,7 +1313,6 @@ static int compat_do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user,
break;
default:
- duprintf("do_arpt_set_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
@@ -1530,17 +1395,13 @@ static int compat_get_entries(struct net *net,
struct compat_arpt_get_entries get;
struct xt_table *t;
- if (*len < sizeof(get)) {
- duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
+ if (*len < sizeof(get))
return -EINVAL;
- }
if (copy_from_user(&get, uptr, sizeof(get)) != 0)
return -EFAULT;
- if (*len != sizeof(struct compat_arpt_get_entries) + get.size) {
- duprintf("compat_get_entries: %u != %zu\n",
- *len, sizeof(get) + get.size);
+ if (*len != sizeof(struct compat_arpt_get_entries) + get.size)
return -EINVAL;
- }
+
get.name[sizeof(get.name) - 1] = '\0';
xt_compat_lock(NFPROTO_ARP);
@@ -1549,16 +1410,13 @@ static int compat_get_entries(struct net *net,
const struct xt_table_info *private = t->private;
struct xt_table_info info;
- duprintf("t->private->number = %u\n", private->number);
ret = compat_table_info(private, &info);
if (!ret && get.size == info.size) {
ret = compat_copy_entries_to_user(private->size,
t, uptr->entrytable);
- } else if (!ret) {
- duprintf("compat_get_entries: I've got %u not %u!\n",
- private->size, get.size);
+ } else if (!ret)
ret = -EAGAIN;
- }
+
xt_compat_flush_offsets(NFPROTO_ARP);
module_put(t->me);
xt_table_unlock(t);
@@ -1610,7 +1468,6 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned
break;
default:
- duprintf("do_arpt_set_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
@@ -1653,7 +1510,6 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
}
default:
- duprintf("do_arpt_get_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
@@ -1698,7 +1554,6 @@ int arpt_register_table(struct net *net,
memcpy(loc_cpu_entry, repl->entries, repl->size);
ret = translate_table(newinfo, loc_cpu_entry, repl);
- duprintf("arpt_register_table: translate table gives %d\n", ret);
if (ret != 0)
goto out_free;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 21ccc19..54906e0 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -35,34 +35,12 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("IPv4 packet filter");
-/*#define DEBUG_IP_FIREWALL*/
-/*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
-/*#define DEBUG_IP_FIREWALL_USER*/
-
-#ifdef DEBUG_IP_FIREWALL
-#define dprintf(format, args...) pr_info(format , ## args)
-#else
-#define dprintf(format, args...)
-#endif
-
-#ifdef DEBUG_IP_FIREWALL_USER
-#define duprintf(format, args...) pr_info(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
#ifdef CONFIG_NETFILTER_DEBUG
#define IP_NF_ASSERT(x) WARN_ON(!(x))
#else
#define IP_NF_ASSERT(x)
#endif
-#if 0
-/* All the better to debug you with... */
-#define static
-#define inline
-#endif
-
void *ipt_alloc_initial_table(const struct xt_table *info)
{
return xt_alloc_initial_table(ipt, IPT);
@@ -85,52 +63,28 @@ ip_packet_match(const struct iphdr *ip,
if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
IPT_INV_SRCIP) ||
FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
- IPT_INV_DSTIP)) {
- dprintf("Source or dest mismatch.\n");
-
- dprintf("SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n",
- &ip->saddr, &ipinfo->smsk.s_addr, &ipinfo->src.s_addr,
- ipinfo->invflags & IPT_INV_SRCIP ? " (INV)" : "");
- dprintf("DST: %pI4 Mask: %pI4 Target: %pI4.%s\n",
- &ip->daddr, &ipinfo->dmsk.s_addr, &ipinfo->dst.s_addr,
- ipinfo->invflags & IPT_INV_DSTIP ? " (INV)" : "");
+ IPT_INV_DSTIP))
return false;
- }
ret = ifname_compare_aligned(indev, ipinfo->iniface, ipinfo->iniface_mask);
- if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
- dprintf("VIA in mismatch (%s vs %s).%s\n",
- indev, ipinfo->iniface,
- ipinfo->invflags & IPT_INV_VIA_IN ? " (INV)" : "");
+ if (FWINV(ret != 0, IPT_INV_VIA_IN))
return false;
- }
ret = ifname_compare_aligned(outdev, ipinfo->outiface, ipinfo->outiface_mask);
- if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
- dprintf("VIA out mismatch (%s vs %s).%s\n",
- outdev, ipinfo->outiface,
- ipinfo->invflags & IPT_INV_VIA_OUT ? " (INV)" : "");
+ if (FWINV(ret != 0, IPT_INV_VIA_OUT))
return false;
- }
/* Check specific protocol */
if (ipinfo->proto &&
- FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO)) {
- dprintf("Packet protocol %hi does not match %hi.%s\n",
- ip->protocol, ipinfo->proto,
- ipinfo->invflags & IPT_INV_PROTO ? " (INV)" : "");
+ FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO))
return false;
- }
/* If we have a fragment rule but the packet is not a fragment
* then we return zero */
- if (FWINV((ipinfo->flags&IPT_F_FRAG) && !isfrag, IPT_INV_FRAG)) {
- dprintf("Fragment rule but not fragment.%s\n",
- ipinfo->invflags & IPT_INV_FRAG ? " (INV)" : "");
+ if (FWINV((ipinfo->flags&IPT_F_FRAG) && !isfrag, IPT_INV_FRAG))
return false;
- }
return true;
}
@@ -138,16 +92,10 @@ ip_packet_match(const struct iphdr *ip,
static bool
ip_checkentry(const struct ipt_ip *ip)
{
- if (ip->flags & ~IPT_F_MASK) {
- duprintf("Unknown flag bits set: %08X\n",
- ip->flags & ~IPT_F_MASK);
+ if (ip->flags & ~IPT_F_MASK)
return false;
- }
- if (ip->invflags & ~IPT_INV_MASK) {
- duprintf("Unknown invflag bits set: %08X\n",
- ip->invflags & ~IPT_INV_MASK);
+ if (ip->invflags & ~IPT_INV_MASK)
return false;
- }
return true;
}
@@ -346,10 +294,6 @@ ipt_do_table(struct sk_buff *skb,
e = get_entry(table_base, private->hook_entry[hook]);
- pr_debug("Entering %s(hook %u), UF %p\n",
- table->name, hook,
- get_entry(table_base, private->underflow[hook]));
-
do {
const struct xt_entry_target *t;
const struct xt_entry_match *ematch;
@@ -396,22 +340,15 @@ ipt_do_table(struct sk_buff *skb,
if (stackidx == 0) {
e = get_entry(table_base,
private->underflow[hook]);
- pr_debug("Underflow (this is normal) "
- "to %p\n", e);
} else {
e = jumpstack[--stackidx];
- pr_debug("Pulled %p out from pos %u\n",
- e, stackidx);
e = ipt_next_entry(e);
}
continue;
}
if (table_base + v != ipt_next_entry(e) &&
- !(e->ip.flags & IPT_F_GOTO)) {
+ !(e->ip.flags & IPT_F_GOTO))
jumpstack[stackidx++] = e;
- pr_debug("Pushed %p into pos %u\n",
- e, stackidx - 1);
- }
e = get_entry(table_base, v);
continue;
@@ -429,18 +366,13 @@ ipt_do_table(struct sk_buff *skb,
/* Verdict */
break;
} while (!acpar.hotdrop);
- pr_debug("Exiting %s; sp at %u\n", __func__, stackidx);
xt_write_recseq_end(addend);
local_bh_enable();
-#ifdef DEBUG_ALLOW_ALL
- return NF_ACCEPT;
-#else
if (acpar.hotdrop)
return NF_DROP;
else return verdict;
-#endif
}
static bool find_jump_target(const struct xt_table_info *t,
@@ -480,11 +412,9 @@ mark_source_chains(const struct xt_table_info *newinfo,
= (void *)ipt_get_target_c(e);
int visited = e->comefrom & (1 << hook);
- if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
- pr_err("iptables: loop hook %u pos %u %08X.\n",
- hook, pos, e->comefrom);
+ if (e->comefrom & (1 << NF_INET_NUMHOOKS))
return 0;
- }
+
e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
/* Unconditional return/END. */
@@ -496,26 +426,13 @@ mark_source_chains(const struct xt_table_info *newinfo,
if ((strcmp(t->target.u.user.name,
XT_STANDARD_TARGET) == 0) &&
- t->verdict < -NF_MAX_VERDICT - 1) {
- duprintf("mark_source_chains: bad "
- "negative verdict (%i)\n",
- t->verdict);
+ t->verdict < -NF_MAX_VERDICT - 1)
return 0;
- }
/* Return: backtrack through the last
big jump. */
do {
e->comefrom ^= (1<<NF_INET_NUMHOOKS);
-#ifdef DEBUG_IP_FIREWALL_USER
- if (e->comefrom
- & (1 << NF_INET_NUMHOOKS)) {
- duprintf("Back unset "
- "on hook %u "
- "rule %u\n",
- hook, pos);
- }
-#endif
oldpos = pos;
pos = e->counters.pcnt;
e->counters.pcnt = 0;
@@ -543,8 +460,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
XT_STANDARD_TARGET) == 0 &&
newpos >= 0) {
/* This a jump; chase it. */
- duprintf("Jump rule %u -> %u\n",
- pos, newpos);
e = (struct ipt_entry *)
(entry0 + newpos);
if (!find_jump_target(newinfo, e))
@@ -561,8 +476,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
pos = newpos;
}
}
-next:
- duprintf("Finished chain %u\n", hook);
+next: ;
}
return 1;
}
@@ -584,18 +498,12 @@ static int
check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
const struct ipt_ip *ip = par->entryinfo;
- int ret;
par->match = m->u.kernel.match;
par->matchinfo = m->data;
- ret = xt_check_match(par, m->u.match_size - sizeof(*m),
- ip->proto, ip->invflags & IPT_INV_PROTO);
- if (ret < 0) {
- duprintf("check failed for `%s'.\n", par->match->name);
- return ret;
- }
- return 0;
+ return xt_check_match(par, m->u.match_size - sizeof(*m),
+ ip->proto, ip->invflags & IPT_INV_PROTO);
}
static int
@@ -606,10 +514,8 @@ find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
m->u.user.revision);
- if (IS_ERR(match)) {
- duprintf("find_check_match: `%s' not found\n", m->u.user.name);
+ if (IS_ERR(match))
return PTR_ERR(match);
- }
m->u.kernel.match = match;
ret = check_match(m, par);
@@ -634,16 +540,9 @@ static int check_target(struct ipt_entry *e, struct net *net, const char *name)
.hook_mask = e->comefrom,
.family = NFPROTO_IPV4,
};
- int ret;
- ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
- e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
- if (ret < 0) {
- duprintf("check failed for `%s'.\n",
- t->u.kernel.target->name);
- return ret;
- }
- return 0;
+ return xt_check_target(&par, t->u.target_size - sizeof(*t),
+ e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
}
static int
@@ -680,7 +579,6 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
t->u.user.revision);
if (IS_ERR(target)) {
- duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
ret = PTR_ERR(target);
goto cleanup_matches;
}
@@ -734,17 +632,12 @@ check_entry_size_and_hooks(struct ipt_entry *e,
if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 ||
(unsigned char *)e + sizeof(struct ipt_entry) >= limit ||
- (unsigned char *)e + e->next_offset > limit) {
- duprintf("Bad offset %p\n", e);
+ (unsigned char *)e + e->next_offset > limit)
return -EINVAL;
- }
if (e->next_offset
- < sizeof(struct ipt_entry) + sizeof(struct xt_entry_target)) {
- duprintf("checking: element %p size %u\n",
- e, e->next_offset);
+ < sizeof(struct ipt_entry) + sizeof(struct xt_entry_target))
return -EINVAL;
- }
if (!ip_checkentry(&e->ip))
return -EINVAL;
@@ -761,12 +654,9 @@ check_entry_size_and_hooks(struct ipt_entry *e,
if ((unsigned char *)e - base == hook_entries[h])
newinfo->hook_entry[h] = hook_entries[h];
if ((unsigned char *)e - base == underflows[h]) {
- if (!check_underflow(e)) {
- pr_debug("Underflows must be unconditional and "
- "use the STANDARD target with "
- "ACCEPT/DROP\n");
+ if (!check_underflow(e))
return -EINVAL;
- }
+
newinfo->underflow[h] = underflows[h];
}
}
@@ -818,7 +708,6 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
newinfo->underflow[i] = 0xFFFFFFFF;
}
- duprintf("translate_table: size %u\n", newinfo->size);
i = 0;
/* Walk through entries, checking offsets. */
xt_entry_foreach(iter, entry0, newinfo->size) {
@@ -835,27 +724,18 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
++newinfo->stacksize;
}
- if (i != repl->num_entries) {
- duprintf("translate_table: %u not %u entries\n",
- i, repl->num_entries);
+ if (i != repl->num_entries)
return -EINVAL;
- }
/* Check hooks all assigned */
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
/* Only hooks which are valid */
if (!(repl->valid_hooks & (1 << i)))
continue;
- if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
- duprintf("Invalid hook entry %u %u\n",
- i, repl->hook_entry[i]);
+ if (newinfo->hook_entry[i] == 0xFFFFFFFF)
return -EINVAL;
- }
- if (newinfo->underflow[i] == 0xFFFFFFFF) {
- duprintf("Invalid underflow %u %u\n",
- i, repl->underflow[i]);
+ if (newinfo->underflow[i] == 0xFFFFFFFF)
return -EINVAL;
- }
}
if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
@@ -1083,11 +963,8 @@ static int get_info(struct net *net, void __user *user,
struct xt_table *t;
int ret;
- if (*len != sizeof(struct ipt_getinfo)) {
- duprintf("length %u != %zu\n", *len,
- sizeof(struct ipt_getinfo));
+ if (*len != sizeof(struct ipt_getinfo))
return -EINVAL;
- }
if (copy_from_user(name, user, sizeof(name)) != 0)
return -EFAULT;
@@ -1145,31 +1022,23 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr,
struct ipt_get_entries get;
struct xt_table *t;
- if (*len < sizeof(get)) {
- duprintf("get_entries: %u < %zu\n", *len, sizeof(get));
+ if (*len < sizeof(get))
return -EINVAL;
- }
if (copy_from_user(&get, uptr, sizeof(get)) != 0)
return -EFAULT;
- if (*len != sizeof(struct ipt_get_entries) + get.size) {
- duprintf("get_entries: %u != %zu\n",
- *len, sizeof(get) + get.size);
+ if (*len != sizeof(struct ipt_get_entries) + get.size)
return -EINVAL;
- }
get.name[sizeof(get.name) - 1] = '\0';
t = xt_find_table_lock(net, AF_INET, get.name);
if (!IS_ERR_OR_NULL(t)) {
const struct xt_table_info *private = t->private;
- duprintf("t->private->number = %u\n", private->number);
if (get.size == private->size)
ret = copy_entries_to_user(private->size,
t, uptr->entrytable);
- else {
- duprintf("get_entries: I've got %u not %u!\n",
- private->size, get.size);
+ else
ret = -EAGAIN;
- }
+
module_put(t->me);
xt_table_unlock(t);
} else
@@ -1205,8 +1074,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
/* You lied! */
if (valid_hooks != t->valid_hooks) {
- duprintf("Valid hook crap: %08X vs %08X\n",
- valid_hooks, t->valid_hooks);
ret = -EINVAL;
goto put_module;
}
@@ -1216,8 +1083,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
goto put_module;
/* Update module usage count based on number of rules */
- duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
- oldinfo->number, oldinfo->initial_entries, newinfo->number);
if ((oldinfo->number > oldinfo->initial_entries) ||
(newinfo->number <= oldinfo->initial_entries))
module_put(t->me);
@@ -1286,8 +1151,6 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
if (ret != 0)
goto free_newinfo;
- duprintf("Translated table\n");
-
ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, tmp.counters);
if (ret)
@@ -1413,11 +1276,9 @@ compat_find_calc_match(struct xt_entry_match *m,
match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
m->u.user.revision);
- if (IS_ERR(match)) {
- duprintf("compat_check_calc_match: `%s' not found\n",
- m->u.user.name);
+ if (IS_ERR(match))
return PTR_ERR(match);
- }
+
m->u.kernel.match = match;
*size += xt_compat_match_offset(match);
return 0;
@@ -1449,20 +1310,14 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
unsigned int j;
int ret, off;
- duprintf("check_compat_entry_size_and_hooks %p\n", e);
if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 ||
(unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit ||
- (unsigned char *)e + e->next_offset > limit) {
- duprintf("Bad offset %p, limit = %p\n", e, limit);
+ (unsigned char *)e + e->next_offset > limit)
return -EINVAL;
- }
if (e->next_offset < sizeof(struct compat_ipt_entry) +
- sizeof(struct compat_xt_entry_target)) {
- duprintf("checking: element %p size %u\n",
- e, e->next_offset);
+ sizeof(struct compat_xt_entry_target))
return -EINVAL;
- }
if (!ip_checkentry(&e->ip))
return -EINVAL;
@@ -1486,8 +1341,6 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
t->u.user.revision);
if (IS_ERR(target)) {
- duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
- t->u.user.name);
ret = PTR_ERR(target);
goto release_matches;
}
@@ -1569,7 +1422,6 @@ translate_compat_table(struct net *net,
size = compatr->size;
info->number = compatr->num_entries;
- duprintf("translate_compat_table: size %u\n", info->size);
j = 0;
xt_compat_lock(AF_INET);
xt_compat_init_offsets(AF_INET, compatr->num_entries);
@@ -1584,11 +1436,8 @@ translate_compat_table(struct net *net,
}
ret = -EINVAL;
- if (j != compatr->num_entries) {
- duprintf("translate_compat_table: %u not %u entries\n",
- j, compatr->num_entries);
+ if (j != compatr->num_entries)
goto out_unlock;
- }
ret = -ENOMEM;
newinfo = xt_alloc_table_info(size);
@@ -1685,8 +1534,6 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
if (ret != 0)
goto free_newinfo;
- duprintf("compat_do_replace: Translated table\n");
-
ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, compat_ptr(tmp.counters));
if (ret)
@@ -1720,7 +1567,6 @@ compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user,
break;
default:
- duprintf("do_ipt_set_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
@@ -1770,19 +1616,15 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
struct compat_ipt_get_entries get;
struct xt_table *t;
- if (*len < sizeof(get)) {
- duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
+ if (*len < sizeof(get))
return -EINVAL;
- }
if (copy_from_user(&get, uptr, sizeof(get)) != 0)
return -EFAULT;
- if (*len != sizeof(struct compat_ipt_get_entries) + get.size) {
- duprintf("compat_get_entries: %u != %zu\n",
- *len, sizeof(get) + get.size);
+ if (*len != sizeof(struct compat_ipt_get_entries) + get.size)
return -EINVAL;
- }
+
get.name[sizeof(get.name) - 1] = '\0';
xt_compat_lock(AF_INET);
@@ -1790,16 +1632,13 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
if (!IS_ERR_OR_NULL(t)) {
const struct xt_table_info *private = t->private;
struct xt_table_info info;
- duprintf("t->private->number = %u\n", private->number);
ret = compat_table_info(private, &info);
- if (!ret && get.size == info.size) {
+ if (!ret && get.size == info.size)
ret = compat_copy_entries_to_user(private->size,
t, uptr->entrytable);
- } else if (!ret) {
- duprintf("compat_get_entries: I've got %u not %u!\n",
- private->size, get.size);
+ else if (!ret)
ret = -EAGAIN;
- }
+
xt_compat_flush_offsets(AF_INET);
module_put(t->me);
xt_table_unlock(t);
@@ -1852,7 +1691,6 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
break;
default:
- duprintf("do_ipt_set_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
@@ -1904,7 +1742,6 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
}
default:
- duprintf("do_ipt_get_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
@@ -2006,7 +1843,6 @@ icmp_match(const struct sk_buff *skb, struct xt_action_param *par)
/* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop.
*/
- duprintf("Dropping evil ICMP tinygram.\n");
par->hotdrop = true;
return false;
}
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 17874e8..63e06c3 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -39,34 +39,12 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("IPv6 packet filter");
-/*#define DEBUG_IP_FIREWALL*/
-/*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
-/*#define DEBUG_IP_FIREWALL_USER*/
-
-#ifdef DEBUG_IP_FIREWALL
-#define dprintf(format, args...) pr_info(format , ## args)
-#else
-#define dprintf(format, args...)
-#endif
-
-#ifdef DEBUG_IP_FIREWALL_USER
-#define duprintf(format, args...) pr_info(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
#ifdef CONFIG_NETFILTER_DEBUG
#define IP_NF_ASSERT(x) WARN_ON(!(x))
#else
#define IP_NF_ASSERT(x)
#endif
-#if 0
-/* All the better to debug you with... */
-#define static
-#define inline
-#endif
-
void *ip6t_alloc_initial_table(const struct xt_table *info)
{
return xt_alloc_initial_table(ip6t, IP6T);
@@ -100,35 +78,18 @@ ip6_packet_match(const struct sk_buff *skb,
if (FWINV(ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk,
&ip6info->src), IP6T_INV_SRCIP) ||
FWINV(ipv6_masked_addr_cmp(&ipv6->daddr, &ip6info->dmsk,
- &ip6info->dst), IP6T_INV_DSTIP)) {
- dprintf("Source or dest mismatch.\n");
-/*
- dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
- ipinfo->smsk.s_addr, ipinfo->src.s_addr,
- ipinfo->invflags & IP6T_INV_SRCIP ? " (INV)" : "");
- dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr,
- ipinfo->dmsk.s_addr, ipinfo->dst.s_addr,
- ipinfo->invflags & IP6T_INV_DSTIP ? " (INV)" : "");*/
+ &ip6info->dst), IP6T_INV_DSTIP))
return false;
- }
ret = ifname_compare_aligned(indev, ip6info->iniface, ip6info->iniface_mask);
- if (FWINV(ret != 0, IP6T_INV_VIA_IN)) {
- dprintf("VIA in mismatch (%s vs %s).%s\n",
- indev, ip6info->iniface,
- ip6info->invflags & IP6T_INV_VIA_IN ? " (INV)" : "");
+ if (FWINV(ret != 0, IP6T_INV_VIA_IN))
return false;
- }
ret = ifname_compare_aligned(outdev, ip6info->outiface, ip6info->outiface_mask);
- if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) {
- dprintf("VIA out mismatch (%s vs %s).%s\n",
- outdev, ip6info->outiface,
- ip6info->invflags & IP6T_INV_VIA_OUT ? " (INV)" : "");
+ if (FWINV(ret != 0, IP6T_INV_VIA_OUT))
return false;
- }
/* ... might want to do something with class and flowlabel here ... */
@@ -145,11 +106,6 @@ ip6_packet_match(const struct sk_buff *skb,
}
*fragoff = _frag_off;
- dprintf("Packet protocol %hi ?= %s%hi.\n",
- protohdr,
- ip6info->invflags & IP6T_INV_PROTO ? "!":"",
- ip6info->proto);
-
if (ip6info->proto == protohdr) {
if (ip6info->invflags & IP6T_INV_PROTO)
return false;
@@ -169,16 +125,11 @@ ip6_packet_match(const struct sk_buff *skb,
static bool
ip6_checkentry(const struct ip6t_ip6 *ipv6)
{
- if (ipv6->flags & ~IP6T_F_MASK) {
- duprintf("Unknown flag bits set: %08X\n",
- ipv6->flags & ~IP6T_F_MASK);
+ if (ipv6->flags & ~IP6T_F_MASK)
return false;
- }
- if (ipv6->invflags & ~IP6T_INV_MASK) {
- duprintf("Unknown invflag bits set: %08X\n",
- ipv6->invflags & ~IP6T_INV_MASK);
+ if (ipv6->invflags & ~IP6T_INV_MASK)
return false;
- }
+
return true;
}
@@ -446,13 +397,9 @@ ip6t_do_table(struct sk_buff *skb,
xt_write_recseq_end(addend);
local_bh_enable();
-#ifdef DEBUG_ALLOW_ALL
- return NF_ACCEPT;
-#else
if (acpar.hotdrop)
return NF_DROP;
else return verdict;
-#endif
}
static bool find_jump_target(const struct xt_table_info *t,
@@ -492,11 +439,9 @@ mark_source_chains(const struct xt_table_info *newinfo,
= (void *)ip6t_get_target_c(e);
int visited = e->comefrom & (1 << hook);
- if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
- pr_err("iptables: loop hook %u pos %u %08X.\n",
- hook, pos, e->comefrom);
+ if (e->comefrom & (1 << NF_INET_NUMHOOKS))
return 0;
- }
+
e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
/* Unconditional return/END. */
@@ -508,26 +453,13 @@ mark_source_chains(const struct xt_table_info *newinfo,
if ((strcmp(t->target.u.user.name,
XT_STANDARD_TARGET) == 0) &&
- t->verdict < -NF_MAX_VERDICT - 1) {
- duprintf("mark_source_chains: bad "
- "negative verdict (%i)\n",
- t->verdict);
+ t->verdict < -NF_MAX_VERDICT - 1)
return 0;
- }
/* Return: backtrack through the last
big jump. */
do {
e->comefrom ^= (1<<NF_INET_NUMHOOKS);
-#ifdef DEBUG_IP_FIREWALL_USER
- if (e->comefrom
- & (1 << NF_INET_NUMHOOKS)) {
- duprintf("Back unset "
- "on hook %u "
- "rule %u\n",
- hook, pos);
- }
-#endif
oldpos = pos;
pos = e->counters.pcnt;
e->counters.pcnt = 0;
@@ -555,8 +487,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
XT_STANDARD_TARGET) == 0 &&
newpos >= 0) {
/* This a jump; chase it. */
- duprintf("Jump rule %u -> %u\n",
- pos, newpos);
e = (struct ip6t_entry *)
(entry0 + newpos);
if (!find_jump_target(newinfo, e))
@@ -573,8 +503,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
pos = newpos;
}
}
-next:
- duprintf("Finished chain %u\n", hook);
+next: ;
}
return 1;
}
@@ -595,19 +524,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
const struct ip6t_ip6 *ipv6 = par->entryinfo;
- int ret;
par->match = m->u.kernel.match;
par->matchinfo = m->data;
- ret = xt_check_match(par, m->u.match_size - sizeof(*m),
- ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
- if (ret < 0) {
- duprintf("ip_tables: check failed for `%s'.\n",
- par.match->name);
- return ret;
- }
- return 0;
+ return xt_check_match(par, m->u.match_size - sizeof(*m),
+ ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
}
static int
@@ -618,10 +540,9 @@ find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name,
m->u.user.revision);
- if (IS_ERR(match)) {
- duprintf("find_check_match: `%s' not found\n", m->u.user.name);
+ if (IS_ERR(match))
return PTR_ERR(match);
- }
+
m->u.kernel.match = match;
ret = check_match(m, par);
@@ -646,17 +567,11 @@ static int check_target(struct ip6t_entry *e, struct net *net, const char *name)
.hook_mask = e->comefrom,
.family = NFPROTO_IPV6,
};
- int ret;
t = ip6t_get_target(e);
- ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
- e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
- if (ret < 0) {
- duprintf("ip_tables: check failed for `%s'.\n",
- t->u.kernel.target->name);
- return ret;
- }
- return 0;
+ return xt_check_target(&par, t->u.target_size - sizeof(*t),
+ e->ipv6.proto,
+ e->ipv6.invflags & IP6T_INV_PROTO);
}
static int
@@ -693,7 +608,6 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name,
t->u.user.revision);
if (IS_ERR(target)) {
- duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
ret = PTR_ERR(target);
goto cleanup_matches;
}
@@ -746,17 +660,12 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 ||
(unsigned char *)e + sizeof(struct ip6t_entry) >= limit ||
- (unsigned char *)e + e->next_offset > limit) {
- duprintf("Bad offset %p\n", e);
+ (unsigned char *)e + e->next_offset > limit)
return -EINVAL;
- }
if (e->next_offset
- < sizeof(struct ip6t_entry) + sizeof(struct xt_entry_target)) {
- duprintf("checking: element %p size %u\n",
- e, e->next_offset);
+ < sizeof(struct ip6t_entry) + sizeof(struct xt_entry_target))
return -EINVAL;
- }
if (!ip6_checkentry(&e->ipv6))
return -EINVAL;
@@ -773,12 +682,9 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
if ((unsigned char *)e - base == hook_entries[h])
newinfo->hook_entry[h] = hook_entries[h];
if ((unsigned char *)e - base == underflows[h]) {
- if (!check_underflow(e)) {
- pr_debug("Underflows must be unconditional and "
- "use the STANDARD target with "
- "ACCEPT/DROP\n");
+ if (!check_underflow(e))
return -EINVAL;
- }
+
newinfo->underflow[h] = underflows[h];
}
}
@@ -830,7 +736,6 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
newinfo->underflow[i] = 0xFFFFFFFF;
}
- duprintf("translate_table: size %u\n", newinfo->size);
i = 0;
/* Walk through entries, checking offsets. */
xt_entry_foreach(iter, entry0, newinfo->size) {
@@ -847,27 +752,18 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
++newinfo->stacksize;
}
- if (i != repl->num_entries) {
- duprintf("translate_table: %u not %u entries\n",
- i, repl->num_entries);
+ if (i != repl->num_entries)
return -EINVAL;
- }
/* Check hooks all assigned */
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
/* Only hooks which are valid */
if (!(repl->valid_hooks & (1 << i)))
continue;
- if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
- duprintf("Invalid hook entry %u %u\n",
- i, repl->hook_entry[i]);
+ if (newinfo->hook_entry[i] == 0xFFFFFFFF)
return -EINVAL;
- }
- if (newinfo->underflow[i] == 0xFFFFFFFF) {
- duprintf("Invalid underflow %u %u\n",
- i, repl->underflow[i]);
+ if (newinfo->underflow[i] == 0xFFFFFFFF)
return -EINVAL;
- }
}
if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
@@ -1095,11 +991,8 @@ static int get_info(struct net *net, void __user *user,
struct xt_table *t;
int ret;
- if (*len != sizeof(struct ip6t_getinfo)) {
- duprintf("length %u != %zu\n", *len,
- sizeof(struct ip6t_getinfo));
+ if (*len != sizeof(struct ip6t_getinfo))
return -EINVAL;
- }
if (copy_from_user(name, user, sizeof(name)) != 0)
return -EFAULT;
@@ -1157,31 +1050,24 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr,
struct ip6t_get_entries get;
struct xt_table *t;
- if (*len < sizeof(get)) {
- duprintf("get_entries: %u < %zu\n", *len, sizeof(get));
+ if (*len < sizeof(get))
return -EINVAL;
- }
if (copy_from_user(&get, uptr, sizeof(get)) != 0)
return -EFAULT;
- if (*len != sizeof(struct ip6t_get_entries) + get.size) {
- duprintf("get_entries: %u != %zu\n",
- *len, sizeof(get) + get.size);
+ if (*len != sizeof(struct ip6t_get_entries) + get.size)
return -EINVAL;
- }
+
get.name[sizeof(get.name) - 1] = '\0';
t = xt_find_table_lock(net, AF_INET6, get.name);
if (!IS_ERR_OR_NULL(t)) {
struct xt_table_info *private = t->private;
- duprintf("t->private->number = %u\n", private->number);
if (get.size == private->size)
ret = copy_entries_to_user(private->size,
t, uptr->entrytable);
- else {
- duprintf("get_entries: I've got %u not %u!\n",
- private->size, get.size);
+ else
ret = -EAGAIN;
- }
+
module_put(t->me);
xt_table_unlock(t);
} else
@@ -1217,8 +1103,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
/* You lied! */
if (valid_hooks != t->valid_hooks) {
- duprintf("Valid hook crap: %08X vs %08X\n",
- valid_hooks, t->valid_hooks);
ret = -EINVAL;
goto put_module;
}
@@ -1228,8 +1112,6 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
goto put_module;
/* Update module usage count based on number of rules */
- duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
- oldinfo->number, oldinfo->initial_entries, newinfo->number);
if ((oldinfo->number > oldinfo->initial_entries) ||
(newinfo->number <= oldinfo->initial_entries))
module_put(t->me);
@@ -1298,8 +1180,6 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
if (ret != 0)
goto free_newinfo;
- duprintf("ip_tables: Translated table\n");
-
ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, tmp.counters);
if (ret)
@@ -1424,11 +1304,9 @@ compat_find_calc_match(struct xt_entry_match *m,
match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name,
m->u.user.revision);
- if (IS_ERR(match)) {
- duprintf("compat_check_calc_match: `%s' not found\n",
- m->u.user.name);
+ if (IS_ERR(match))
return PTR_ERR(match);
- }
+
m->u.kernel.match = match;
*size += xt_compat_match_offset(match);
return 0;
@@ -1460,20 +1338,14 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
unsigned int j;
int ret, off;
- duprintf("check_compat_entry_size_and_hooks %p\n", e);
if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 ||
(unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit ||
- (unsigned char *)e + e->next_offset > limit) {
- duprintf("Bad offset %p, limit = %p\n", e, limit);
+ (unsigned char *)e + e->next_offset > limit)
return -EINVAL;
- }
if (e->next_offset < sizeof(struct compat_ip6t_entry) +
- sizeof(struct compat_xt_entry_target)) {
- duprintf("checking: element %p size %u\n",
- e, e->next_offset);
+ sizeof(struct compat_xt_entry_target))
return -EINVAL;
- }
if (!ip6_checkentry(&e->ipv6))
return -EINVAL;
@@ -1497,8 +1369,6 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name,
t->u.user.revision);
if (IS_ERR(target)) {
- duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
- t->u.user.name);
ret = PTR_ERR(target);
goto release_matches;
}
@@ -1577,7 +1447,6 @@ translate_compat_table(struct net *net,
size = compatr->size;
info->number = compatr->num_entries;
- duprintf("translate_compat_table: size %u\n", info->size);
j = 0;
xt_compat_lock(AF_INET6);
xt_compat_init_offsets(AF_INET6, compatr->num_entries);
@@ -1592,11 +1461,8 @@ translate_compat_table(struct net *net,
}
ret = -EINVAL;
- if (j != compatr->num_entries) {
- duprintf("translate_compat_table: %u not %u entries\n",
- j, compatr->num_entries);
+ if (j != compatr->num_entries)
goto out_unlock;
- }
ret = -ENOMEM;
newinfo = xt_alloc_table_info(size);
@@ -1687,8 +1553,6 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
if (ret != 0)
goto free_newinfo;
- duprintf("compat_do_replace: Translated table\n");
-
ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
tmp.num_counters, compat_ptr(tmp.counters));
if (ret)
@@ -1722,7 +1586,6 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user,
break;
default:
- duprintf("do_ip6t_set_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
@@ -1772,19 +1635,15 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
struct compat_ip6t_get_entries get;
struct xt_table *t;
- if (*len < sizeof(get)) {
- duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
+ if (*len < sizeof(get))
return -EINVAL;
- }
if (copy_from_user(&get, uptr, sizeof(get)) != 0)
return -EFAULT;
- if (*len != sizeof(struct compat_ip6t_get_entries) + get.size) {
- duprintf("compat_get_entries: %u != %zu\n",
- *len, sizeof(get) + get.size);
+ if (*len != sizeof(struct compat_ip6t_get_entries) + get.size)
return -EINVAL;
- }
+
get.name[sizeof(get.name) - 1] = '\0';
xt_compat_lock(AF_INET6);
@@ -1792,16 +1651,13 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
if (!IS_ERR_OR_NULL(t)) {
const struct xt_table_info *private = t->private;
struct xt_table_info info;
- duprintf("t->private->number = %u\n", private->number);
ret = compat_table_info(private, &info);
- if (!ret && get.size == info.size) {
+ if (!ret && get.size == info.size)
ret = compat_copy_entries_to_user(private->size,
t, uptr->entrytable);
- } else if (!ret) {
- duprintf("compat_get_entries: I've got %u not %u!\n",
- private->size, get.size);
+ else if (!ret)
ret = -EAGAIN;
- }
+
xt_compat_flush_offsets(AF_INET6);
module_put(t->me);
xt_table_unlock(t);
@@ -1854,7 +1710,6 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
break;
default:
- duprintf("do_ip6t_set_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
@@ -1906,7 +1761,6 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
}
default:
- duprintf("do_ip6t_get_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
@@ -2008,7 +1862,6 @@ icmp6_match(const struct sk_buff *skb, struct xt_action_param *par)
/* We've been asked to examine this packet, and we
* can't. Hence, no choice but to drop.
*/
- duprintf("Dropping evil ICMP tinygram.\n");
par->hotdrop = true;
return false;
}
--
2.1.4
^ permalink raw reply related
* [PATCH 25/36] netfilter: conntrack: introduce nf_ct_acct_update()
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
Introduce a helper function to update conntrack counters.
__nf_ct_kill_acct() was unnecessarily subtracting skb_network_offset()
that is expected to be zero from the ipv4/ipv6 hooks.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_core.c | 42 ++++++++++++++++++---------------------
1 file changed, 19 insertions(+), 23 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index f72ede1..25e0c26 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -602,6 +602,21 @@ out:
}
EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert);
+static inline void nf_ct_acct_update(struct nf_conn *ct,
+ enum ip_conntrack_info ctinfo,
+ unsigned int len)
+{
+ struct nf_conn_acct *acct;
+
+ acct = nf_conn_acct_find(ct);
+ if (acct) {
+ struct nf_conn_counter *counter = acct->counter;
+
+ atomic64_inc(&counter[CTINFO2DIR(ctinfo)].packets);
+ atomic64_add(len, &counter[CTINFO2DIR(ctinfo)].bytes);
+ }
+}
+
/* Confirm a connection given skb; places it in hash table */
int
__nf_conntrack_confirm(struct sk_buff *skb)
@@ -1258,17 +1273,8 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
}
acct:
- if (do_acct) {
- struct nf_conn_acct *acct;
-
- acct = nf_conn_acct_find(ct);
- if (acct) {
- struct nf_conn_counter *counter = acct->counter;
-
- atomic64_inc(&counter[CTINFO2DIR(ctinfo)].packets);
- atomic64_add(skb->len, &counter[CTINFO2DIR(ctinfo)].bytes);
- }
- }
+ if (do_acct)
+ nf_ct_acct_update(ct, ctinfo, skb->len);
}
EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
@@ -1277,18 +1283,8 @@ bool __nf_ct_kill_acct(struct nf_conn *ct,
const struct sk_buff *skb,
int do_acct)
{
- if (do_acct) {
- struct nf_conn_acct *acct;
-
- acct = nf_conn_acct_find(ct);
- if (acct) {
- struct nf_conn_counter *counter = acct->counter;
-
- atomic64_inc(&counter[CTINFO2DIR(ctinfo)].packets);
- atomic64_add(skb->len - skb_network_offset(skb),
- &counter[CTINFO2DIR(ctinfo)].bytes);
- }
- }
+ if (do_acct)
+ nf_ct_acct_update(ct, ctinfo, skb->len);
if (del_timer(&ct->timeout)) {
ct->timeout.function((unsigned long)ct);
--
2.1.4
^ permalink raw reply related
* [PATCH 21/36] netfilter: conntrack: make netns address part of hash
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
Once we place all conntracks into a global hash table we want them to be
spread across entire hash table, even if namespaces have overlapping ip
addresses.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_core.c | 35 ++++++++++++++++++-----------------
1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 10ae2ee..ebafa77 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -54,6 +54,7 @@
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_core.h>
#include <net/netfilter/nf_nat_helper.h>
+#include <net/netns/hash.h>
#define NF_CONNTRACK_VERSION "0.5.0"
@@ -144,9 +145,11 @@ EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked);
static unsigned int nf_conntrack_hash_rnd __read_mostly;
-static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple)
+static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple,
+ const struct net *net)
{
unsigned int n;
+ u32 seed;
get_random_once(&nf_conntrack_hash_rnd, sizeof(nf_conntrack_hash_rnd));
@@ -154,32 +157,29 @@ static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple)
* destination ports (which is a multiple of 4) and treat the last
* three bytes manually.
*/
+ seed = nf_conntrack_hash_rnd ^ net_hash_mix(net);
n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32);
- return jhash2((u32 *)tuple, n, nf_conntrack_hash_rnd ^
+ return jhash2((u32 *)tuple, n, seed ^
(((__force __u16)tuple->dst.u.all << 16) |
tuple->dst.protonum));
}
-static u32 __hash_bucket(u32 hash, unsigned int size)
-{
- return reciprocal_scale(hash, size);
-}
-
static u32 hash_bucket(u32 hash, const struct net *net)
{
- return __hash_bucket(hash, net->ct.htable_size);
+ return reciprocal_scale(hash, net->ct.htable_size);
}
-static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
- unsigned int size)
+static u32 __hash_conntrack(const struct net *net,
+ const struct nf_conntrack_tuple *tuple,
+ unsigned int size)
{
- return __hash_bucket(hash_conntrack_raw(tuple), size);
+ return reciprocal_scale(hash_conntrack_raw(tuple, net), size);
}
-static inline u_int32_t hash_conntrack(const struct net *net,
- const struct nf_conntrack_tuple *tuple)
+static u32 hash_conntrack(const struct net *net,
+ const struct nf_conntrack_tuple *tuple)
{
- return __hash_conntrack(tuple, net->ct.htable_size);
+ return __hash_conntrack(net, tuple, net->ct.htable_size);
}
bool
@@ -535,7 +535,7 @@ nf_conntrack_find_get(struct net *net, const struct nf_conntrack_zone *zone,
const struct nf_conntrack_tuple *tuple)
{
return __nf_conntrack_find_get(net, zone, tuple,
- hash_conntrack_raw(tuple));
+ hash_conntrack_raw(tuple, net));
}
EXPORT_SYMBOL_GPL(nf_conntrack_find_get);
@@ -1041,7 +1041,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
/* look for tuple match */
zone = nf_ct_zone_tmpl(tmpl, skb, &tmp);
- hash = hash_conntrack_raw(&tuple);
+ hash = hash_conntrack_raw(&tuple, net);
h = __nf_conntrack_find_get(net, zone, &tuple, hash);
if (!h) {
h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto,
@@ -1605,7 +1605,8 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
struct nf_conntrack_tuple_hash, hnnode);
ct = nf_ct_tuplehash_to_ctrack(h);
hlist_nulls_del_rcu(&h->hnnode);
- bucket = __hash_conntrack(&h->tuple, hashsize);
+ bucket = __hash_conntrack(nf_ct_net(ct),
+ &h->tuple, hashsize);
hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]);
}
}
--
2.1.4
^ permalink raw reply related
* [PATCH 17/36] netfilter: conntrack: don't attempt to iterate over empty table
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
Once we place all conntracks into same table iteration becomes more
costly because the table contains conntracks that we are not interested
in (belonging to other netns).
So don't bother scanning if the current namespace has no entries.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 29fa08b..f2e75a5 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1428,6 +1428,9 @@ void nf_ct_iterate_cleanup(struct net *net,
might_sleep();
+ if (atomic_read(&net->ct.count) == 0)
+ return;
+
while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
/* Time to push up daises... */
if (del_timer(&ct->timeout))
--
2.1.4
^ permalink raw reply related
* [PATCH 16/36] netfilter: conntrack: fix lookup race during hash resize
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
When resizing the conntrack hash table at runtime via
echo 42 > /sys/module/nf_conntrack/parameters/hashsize, we are racing with
the conntrack lookup path -- reads can happen in parallel and nothing
prevents readers from observing a the newly allocated hash but the old
size (or vice versa).
So access to hash[bucket] can trigger OOB read access in case the table got
expanded and we saw the new size but the old hash pointer (or it got shrunk
and we got new hash ptr but the size of the old and larger table):
kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] SMP KASAN
CPU: 0 PID: 3 Comm: ksoftirqd/0 Not tainted 4.6.0-rc2+ #107
[..]
Call Trace:
[<ffffffff822c3d6a>] ? nf_conntrack_tuple_taken+0x12a/0xe90
[<ffffffff822c3ac1>] ? nf_ct_invert_tuplepr+0x221/0x3a0
[<ffffffff8230e703>] get_unique_tuple+0xfb3/0x2760
Use generation counter to obtain the address/length of the same table.
Also add a synchronize_net before freeing the old hash.
AFAICS, without it we might access ct_hash[bucket] after ct_hash has been
freed, provided that lockless reader got delayed by another event:
CPU1 CPU2
seq_begin
seq_retry
<delay> resize occurs
free oldhash
for_each(oldhash[size])
Note that resize is only supported in init_netns, it took over 2 minutes
of constant resizing+flooding to produce the warning, so this isn't a
big problem in practice.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_core.c | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 1b63359..29fa08b 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -469,11 +469,18 @@ ____nf_conntrack_find(struct net *net, const struct nf_conntrack_zone *zone,
const struct nf_conntrack_tuple *tuple, u32 hash)
{
struct nf_conntrack_tuple_hash *h;
+ struct hlist_nulls_head *ct_hash;
struct hlist_nulls_node *n;
- unsigned int bucket = hash_bucket(hash, net);
+ unsigned int bucket, sequence;
begin:
- hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[bucket], hnnode) {
+ do {
+ sequence = read_seqcount_begin(&nf_conntrack_generation);
+ bucket = hash_bucket(hash, net);
+ ct_hash = net->ct.hash;
+ } while (read_seqcount_retry(&nf_conntrack_generation, sequence));
+
+ hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[bucket], hnnode) {
if (nf_ct_key_equal(h, tuple, zone)) {
NF_CT_STAT_INC_ATOMIC(net, found);
return h;
@@ -722,15 +729,21 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
struct net *net = nf_ct_net(ignored_conntrack);
const struct nf_conntrack_zone *zone;
struct nf_conntrack_tuple_hash *h;
+ struct hlist_nulls_head *ct_hash;
+ unsigned int hash, sequence;
struct hlist_nulls_node *n;
struct nf_conn *ct;
- unsigned int hash;
zone = nf_ct_zone(ignored_conntrack);
- hash = hash_conntrack(net, tuple);
rcu_read_lock();
- hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnnode) {
+ do {
+ sequence = read_seqcount_begin(&nf_conntrack_generation);
+ hash = hash_conntrack(net, tuple);
+ ct_hash = net->ct.hash;
+ } while (read_seqcount_retry(&nf_conntrack_generation, sequence));
+
+ hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[hash], hnnode) {
ct = nf_ct_tuplehash_to_ctrack(h);
if (ct != ignored_conntrack &&
nf_ct_tuple_equal(tuple, &h->tuple) &&
@@ -1607,6 +1620,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
nf_conntrack_all_unlock();
local_bh_enable();
+ synchronize_net();
nf_ct_free_hashtable(old_hash, old_size);
return 0;
}
--
2.1.4
^ permalink raw reply related
* [PATCH 15/36] netfilter: conntrack: keep BH enabled during lookup
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
No need to disable BH here anymore:
stats are switched to _ATOMIC variant (== this_cpu_inc()), which
nowadays generates same code as the non _ATOMIC NF_STAT, at least on x86.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_conntrack_core.c | 25 ++++++++-----------------
1 file changed, 8 insertions(+), 17 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 1fd0ff1..1b63359 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -472,18 +472,13 @@ ____nf_conntrack_find(struct net *net, const struct nf_conntrack_zone *zone,
struct hlist_nulls_node *n;
unsigned int bucket = hash_bucket(hash, net);
- /* Disable BHs the entire time since we normally need to disable them
- * at least once for the stats anyway.
- */
- local_bh_disable();
begin:
hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[bucket], hnnode) {
if (nf_ct_key_equal(h, tuple, zone)) {
- NF_CT_STAT_INC(net, found);
- local_bh_enable();
+ NF_CT_STAT_INC_ATOMIC(net, found);
return h;
}
- NF_CT_STAT_INC(net, searched);
+ NF_CT_STAT_INC_ATOMIC(net, searched);
}
/*
* if the nulls value we got at the end of this lookup is
@@ -491,10 +486,9 @@ begin:
* We probably met an item that was moved to another chain.
*/
if (get_nulls_value(n) != bucket) {
- NF_CT_STAT_INC(net, search_restart);
+ NF_CT_STAT_INC_ATOMIC(net, search_restart);
goto begin;
}
- local_bh_enable();
return NULL;
}
@@ -735,22 +729,19 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
zone = nf_ct_zone(ignored_conntrack);
hash = hash_conntrack(net, tuple);
- /* Disable BHs the entire time since we need to disable them at
- * least once for the stats anyway.
- */
- rcu_read_lock_bh();
+ rcu_read_lock();
hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnnode) {
ct = nf_ct_tuplehash_to_ctrack(h);
if (ct != ignored_conntrack &&
nf_ct_tuple_equal(tuple, &h->tuple) &&
nf_ct_zone_equal(ct, zone, NF_CT_DIRECTION(h))) {
- NF_CT_STAT_INC(net, found);
- rcu_read_unlock_bh();
+ NF_CT_STAT_INC_ATOMIC(net, found);
+ rcu_read_unlock();
return 1;
}
- NF_CT_STAT_INC(net, searched);
+ NF_CT_STAT_INC_ATOMIC(net, searched);
}
- rcu_read_unlock_bh();
+ rcu_read_unlock();
return 0;
}
--
2.1.4
^ permalink raw reply related
* [PATCH 14/36] netfilter: nftables: add connlabel set support
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
Conntrack labels are currently sized depending on the iptables
ruleset, i.e. if we're asked to test or set bits 1, 2, and 65 then we
would allocate enough room to store at least bit 65.
However, with nft, the input is just a register with arbitrary runtime
content.
We therefore ask for the upper ceiling we currently have, which is
enough room to store 128 bits.
Alternatively, we could alter nf_connlabel_replace to increase
net->ct.label_words at run time, but since 128 bits is not that
big we'd only save sizeof(long) so it doesn't seem worth it for now.
This follows a similar approach that xtables 'connlabel'
match uses, so when user inputs
ct label set bar
then we will set the bit used by the 'bar' label and leave the rest alone.
This is done by passing the sreg content to nf_connlabels_replace
as both value and mask argument.
Labels (bits) already set thus cannot be re-set to zero, but
this is not supported by xtables connlabel match either.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_ct.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 25998fa..137e308 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -198,6 +198,14 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
}
break;
#endif
+#ifdef CONFIG_NF_CONNTRACK_LABELS
+ case NFT_CT_LABELS:
+ nf_connlabels_replace(ct,
+ ®s->data[priv->sreg],
+ ®s->data[priv->sreg],
+ NF_CT_LABELS_MAX_SIZE / sizeof(u32));
+ break;
+#endif
default:
break;
}
@@ -365,6 +373,16 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
len = FIELD_SIZEOF(struct nf_conn, mark);
break;
#endif
+#ifdef CONFIG_NF_CONNTRACK_LABELS
+ case NFT_CT_LABELS:
+ if (tb[NFTA_CT_DIRECTION])
+ return -EINVAL;
+ len = NF_CT_LABELS_MAX_SIZE;
+ err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1);
+ if (err)
+ return err;
+ break;
+#endif
default:
return -EOPNOTSUPP;
}
@@ -384,6 +402,18 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
static void nft_ct_destroy(const struct nft_ctx *ctx,
const struct nft_expr *expr)
{
+ struct nft_ct *priv = nft_expr_priv(expr);
+
+ switch (priv->key) {
+#ifdef CONFIG_NF_CONNTRACK_LABELS
+ case NFT_CT_LABELS:
+ nf_connlabels_put(ctx->net);
+ break;
+#endif
+ default:
+ break;
+ }
+
nft_ct_l3proto_module_put(ctx->afi->family);
}
--
2.1.4
^ permalink raw reply related
* [PATCH 08/36] netfilter: nf_tables: parse element flags from nft_del_setelem()
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
Parse flags and pass them to the set via ->deactivate() to check if we
remove the right element from the intervals.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 38 +++++++++++++++++++++++++++++++++-----
1 file changed, 33 insertions(+), 5 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 1b3210b..73c8fad 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3592,9 +3592,13 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
const struct nlattr *attr)
{
struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
+ struct nft_set_ext_tmpl tmpl;
struct nft_data_desc desc;
struct nft_set_elem elem;
+ struct nft_set_ext *ext;
struct nft_trans *trans;
+ u32 flags = 0;
+ void *priv;
int err;
err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
@@ -3606,6 +3610,14 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
if (nla[NFTA_SET_ELEM_KEY] == NULL)
goto err1;
+ nft_set_ext_prepare(&tmpl);
+
+ err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
+ if (err < 0)
+ return err;
+ if (flags != 0)
+ nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
+
err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
nla[NFTA_SET_ELEM_KEY]);
if (err < 0)
@@ -3615,24 +3627,40 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
goto err2;
+ nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
+
+ err = -ENOMEM;
+ elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
+ GFP_KERNEL);
+ if (elem.priv == NULL)
+ goto err2;
+
+ ext = nft_set_elem_ext(set, elem.priv);
+ if (flags)
+ *nft_set_ext_flags(ext) = flags;
+
trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
if (trans == NULL) {
err = -ENOMEM;
- goto err2;
+ goto err3;
}
- elem.priv = set->ops->deactivate(set, &elem);
- if (elem.priv == NULL) {
+ priv = set->ops->deactivate(set, &elem);
+ if (priv == NULL) {
err = -ENOENT;
- goto err3;
+ goto err4;
}
+ kfree(elem.priv);
+ elem.priv = priv;
nft_trans_elem(trans) = elem;
list_add_tail(&trans->list, &ctx->net->nft.commit_list);
return 0;
-err3:
+err4:
kfree(trans);
+err3:
+ kfree(elem.priv);
err2:
nft_data_uninit(&elem.key.val, desc.type);
err1:
--
2.1.4
^ permalink raw reply related
* [PATCH 06/36] netfilter: conntrack: use get_random_once for conntrack hash seed
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
As earlier commit removed accessed to the hash from other files we can
also make it static.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_conntrack.h | 2 --
net/netfilter/nf_conntrack_core.c | 26 +++-----------------------
2 files changed, 3 insertions(+), 25 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index fde4068..dd78bea 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -289,8 +289,6 @@ struct kernel_param;
int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
extern unsigned int nf_conntrack_htable_size;
extern unsigned int nf_conntrack_max;
-extern unsigned int nf_conntrack_hash_rnd;
-void init_nf_conntrack_hash_rnd(void);
struct nf_conn *nf_ct_tmpl_alloc(struct net *net,
const struct nf_conntrack_zone *zone,
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index a53c009..1fd0ff1 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -142,13 +142,14 @@ EXPORT_SYMBOL_GPL(nf_conntrack_max);
DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked);
-unsigned int nf_conntrack_hash_rnd __read_mostly;
-EXPORT_SYMBOL_GPL(nf_conntrack_hash_rnd);
+static unsigned int nf_conntrack_hash_rnd __read_mostly;
static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple)
{
unsigned int n;
+ get_random_once(&nf_conntrack_hash_rnd, sizeof(nf_conntrack_hash_rnd));
+
/* The direction must be ignored, so we hash everything up to the
* destination ports (which is a multiple of 4) and treat the last
* three bytes manually.
@@ -815,21 +816,6 @@ restart:
return dropped;
}
-void init_nf_conntrack_hash_rnd(void)
-{
- unsigned int rand;
-
- /*
- * Why not initialize nf_conntrack_rnd in a "init()" function ?
- * Because there isn't enough entropy when system initializing,
- * and we initialize it as late as possible.
- */
- do {
- get_random_bytes(&rand, sizeof(rand));
- } while (!rand);
- cmpxchg(&nf_conntrack_hash_rnd, 0, rand);
-}
-
static struct nf_conn *
__nf_conntrack_alloc(struct net *net,
const struct nf_conntrack_zone *zone,
@@ -839,12 +825,6 @@ __nf_conntrack_alloc(struct net *net,
{
struct nf_conn *ct;
- if (unlikely(!nf_conntrack_hash_rnd)) {
- init_nf_conntrack_hash_rnd();
- /* recompute the hash as nf_conntrack_hash_rnd is initialized */
- hash = hash_conntrack_raw(orig);
- }
-
/* We don't want any race condition at early drop stage */
atomic_inc(&net->ct.count);
--
2.1.4
^ permalink raw reply related
* [PATCH 04/36] netfilter: conntrack: move generation seqcnt out of netns_ct
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Florian Westphal <fw@strlen.de>
We only allow rehash in init namespace, so we only use
init_ns.generation. And even if we would allow it, it makes no sense
as the conntrack locks are global; any ongoing rehash prevents insert/
delete.
So make this private to nf_conntrack_core instead.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netns/conntrack.h | 1 -
net/netfilter/nf_conntrack_core.c | 20 +++++++++++---------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index 723b61c..b052785 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -94,7 +94,6 @@ struct netns_ct {
int sysctl_checksum;
unsigned int htable_size;
- seqcount_t generation;
struct kmem_cache *nf_conntrack_cachep;
struct hlist_nulls_head *hash;
struct hlist_head *expect_hash;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 2fd6074..a53c009 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -69,6 +69,7 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(nf_conntrack_expect_lock);
EXPORT_SYMBOL_GPL(nf_conntrack_expect_lock);
static __read_mostly spinlock_t nf_conntrack_locks_all_lock;
+static __read_mostly seqcount_t nf_conntrack_generation;
static __read_mostly bool nf_conntrack_locks_all;
void nf_conntrack_lock(spinlock_t *lock) __acquires(lock)
@@ -107,7 +108,7 @@ static bool nf_conntrack_double_lock(struct net *net, unsigned int h1,
spin_lock_nested(&nf_conntrack_locks[h1],
SINGLE_DEPTH_NESTING);
}
- if (read_seqcount_retry(&net->ct.generation, sequence)) {
+ if (read_seqcount_retry(&nf_conntrack_generation, sequence)) {
nf_conntrack_double_unlock(h1, h2);
return true;
}
@@ -393,7 +394,7 @@ static void nf_ct_delete_from_lists(struct nf_conn *ct)
local_bh_disable();
do {
- sequence = read_seqcount_begin(&net->ct.generation);
+ sequence = read_seqcount_begin(&nf_conntrack_generation);
hash = hash_conntrack(net,
&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
reply_hash = hash_conntrack(net,
@@ -560,7 +561,7 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
local_bh_disable();
do {
- sequence = read_seqcount_begin(&net->ct.generation);
+ sequence = read_seqcount_begin(&nf_conntrack_generation);
hash = hash_conntrack(net,
&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
reply_hash = hash_conntrack(net,
@@ -628,7 +629,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
local_bh_disable();
do {
- sequence = read_seqcount_begin(&net->ct.generation);
+ sequence = read_seqcount_begin(&nf_conntrack_generation);
/* reuse the hash saved before */
hash = *(unsigned long *)&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev;
hash = hash_bucket(hash, net);
@@ -771,12 +772,12 @@ static noinline int early_drop(struct net *net, unsigned int _hash)
local_bh_disable();
restart:
- sequence = read_seqcount_begin(&net->ct.generation);
+ sequence = read_seqcount_begin(&nf_conntrack_generation);
hash = hash_bucket(_hash, net);
for (; i < net->ct.htable_size; i++) {
lockp = &nf_conntrack_locks[hash % CONNTRACK_LOCKS];
nf_conntrack_lock(lockp);
- if (read_seqcount_retry(&net->ct.generation, sequence)) {
+ if (read_seqcount_retry(&nf_conntrack_generation, sequence)) {
spin_unlock(lockp);
goto restart;
}
@@ -1607,7 +1608,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
local_bh_disable();
nf_conntrack_all_lock();
- write_seqcount_begin(&init_net.ct.generation);
+ write_seqcount_begin(&nf_conntrack_generation);
/* Lookups in the old hash might happen in parallel, which means we
* might get false negatives during connection lookup. New connections
@@ -1631,7 +1632,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
init_net.ct.htable_size = nf_conntrack_htable_size = hashsize;
init_net.ct.hash = hash;
- write_seqcount_end(&init_net.ct.generation);
+ write_seqcount_end(&nf_conntrack_generation);
nf_conntrack_all_unlock();
local_bh_enable();
@@ -1657,6 +1658,8 @@ int nf_conntrack_init_start(void)
int max_factor = 8;
int i, ret, cpu;
+ seqcount_init(&nf_conntrack_generation);
+
for (i = 0; i < CONNTRACK_LOCKS; i++)
spin_lock_init(&nf_conntrack_locks[i]);
@@ -1783,7 +1786,6 @@ int nf_conntrack_init_net(struct net *net)
int cpu;
atomic_set(&net->ct.count, 0);
- seqcount_init(&net->ct.generation);
net->ct.pcpu_lists = alloc_percpu(struct ct_pcpu);
if (!net->ct.pcpu_lists)
--
2.1.4
^ permalink raw reply related
* [PATCH 03/36] ipvs: don't alter conntrack in OPS mode
From: Pablo Neira Ayuso @ 2016-05-09 18:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
In-Reply-To: <1462819614-5402-1-git-send-email-pablo@netfilter.org>
From: Marco Angaroni <marcoangaroni@gmail.com>
When using OPS mode in conjunction with SIP persistent-engine, packets
originating from the same ip-address/port could be balanced to different
real servers, and (to properly handle SIP responses) OPS connections
are created in the in-out direction too, where ip_vs_update_conntrack()
is called to modify the reply tuple.
As a result, there can be collision of conntrack tuples, causing random
packet drops, as explained below:
conntrack1: orig=CIP->VIP, reply=RIP1->CIP
conntrack2: orig=RIP2->CIP, reply=CIP->VIP
Tuple CIP->VIP is both in orig of conntrack1 and reply of conntrack2.
The collision triggers packet drop inside nf_conntrack processing.
In addition, the current implementation deletes the conntrack object at
every expire of an OPS connection (once every forwarded packet), to have
it recreated from scratch at next packet traversing IPVS.
Since in OPS mode, by definition, we don't expect any associated
response, the choices implemented in this patch are:
a) don't call nf_conntrack_alter_reply() for OPS connections inside
ip_vs_update_conntrack().
b) don't delete the conntrack object at OPS connection expire.
The result is that created conntrack objects for each tuple CIP->VIP,
RIP-N->CIP, etc. are left in UNREPLIED state and not modified by IPVS
OPS connection management. This eliminates packet drops and leaves
a single conntrack object for each tuple packets are sent from.
Signed-off-by: Marco Angaroni <marcoangaroni@gmail.com>
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
net/netfilter/ipvs/ip_vs_conn.c | 3 ++-
net/netfilter/ipvs/ip_vs_nfct.c | 4 ++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index dd75d41..292365f 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -836,7 +836,8 @@ 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) {
+ if ((cp->flags & IP_VS_CONN_F_NFCT) &&
+ !(cp->flags & IP_VS_CONN_F_ONE_PACKET)) {
/* Do not access conntracks during subsys cleanup
* because nf_conntrack_find_get can not be used after
* conntrack cleanup for the net.
diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c
index 30434fb..f04fd8d 100644
--- a/net/netfilter/ipvs/ip_vs_nfct.c
+++ b/net/netfilter/ipvs/ip_vs_nfct.c
@@ -93,6 +93,10 @@ ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin)
if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
return;
+ /* Never alter conntrack for OPS conns (no reply is expected) */
+ if (cp->flags & IP_VS_CONN_F_ONE_PACKET)
+ return;
+
/* Alter reply only in original direction */
if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
return;
--
2.1.4
^ permalink raw reply related
* Re: rtk8168 driver help needed
From: Murali Karicheri @ 2016-05-09 18:13 UTC (permalink / raw)
To: Francois Romieu; +Cc: open list:TI NETCP ETHERNET DRIVER
In-Reply-To: <5730C7F3.6030905@ti.com>
On 05/09/2016 01:25 PM, Murali Karicheri wrote:
> On 05/09/2016 10:54 AM, Murali Karicheri wrote:
>> Francois,
>>
>> Thanks for responding.
>>
>> On 05/07/2016 04:35 AM, Francois Romieu wrote:
>>> Murali Karicheri <m-karicheri2@ti.com> :
>>> [...]
>>>> I am trying to integrate the rtl8168 PCIe card to have Ethernet functional
>>>> on my Keystone EVM.
>>>
>>> Which (EVM) one ?
>> K2G EVM. This is a new EVM for which work has been started to add it to upstream
>> kernel. But it not there yet. The PCIe h/w in the K2G SoC is a re-use from
>> existing SoC such as K2E. The PCIe controller (Root complex a.k.a RC) driver
>> based on this PCIe h/w works fine on K2E EVM with a Marvel SATA controller
>> connected to the PCIe port. On K2G EVM, I have a PCIe slot to which I have
>> plugged the rtl8168 PCIe card and power on with the log I had sent you. The
>> serdes driver is responsible for link setup seems to work fine, link is up and
>> could detect the rtl8168 below.
>>>
>>>> I purchased the rtl8111c Gib card from Amazon. The Card is detected
>>>> by the RC and I can see it is enumerated and show up when doing lspci command.
>>>
>>> What does "the RC" mean ? A different PC ?
>>
>> RC - Root Complex (PCIe controller - drivers/pci/host/pci-keystone.c, a designware
>> based PCIe controller driver)
>>
>> The the PCIe controller driver bindings...
>>
>> pcie0_phy: phy@2320000 {
>> #phy-cells = <0>;
>> compatible = "ti,keystone-serdes-pcie";
>> reg = <0x02320000 0x4000>;
>> link-rate-kbps = <5000000>;
>> num-lanes = <1>;
>> status = "disabled";
>> };
>>
>> pcie0: pcie@21800000 {
>> compatible = "ti,keystone-pcie", "snps,dw-pcie";
>> power-domains = <&k2g_pds K2G_DEV_PCIE0>;
>> clocks = <&k2g_clks K2G_DEV_PCIE0 K2G_DEV_PCIE_VBUS_CLK>;
>> clock-names = "pcie";
>> #address-cells = <3>;
>> #size-cells = <2>;
>> reg = <0x21801000 0x2000>, <0x21800000 0x1000>, <0x02620128 4>;
>> ranges = <0x81000000 0 0 0x23250000 0 0x4000
>> 0x82000000 0 0x50000000 0x50000000 0 0x10000000>;
>>
>> status = "disabled";
>> device_type = "pci";
>> num-lanes = <1>;
>> phys = <&pcie0_phy>;
>>
>> #interrupt-cells = <1>;
>> interrupt-map-mask = <0 0 0 7>;
>> interrupt-map = <0 0 0 1 &pcie_intc0 0>, /* INT A */
>> <0 0 0 2 &pcie_intc0 1>, /* INT B */
>> <0 0 0 3 &pcie_intc0 2>, /* INT C */
>> <0 0 0 4 &pcie_intc0 3>; /* INT D */
>> pcie_msi_intc0: msi-interrupt-controller {
>> interrupt-controller;
>> #interrupt-cells = <1>;
>> interrupt-parent = <&gic>;
>> interrupts = <GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 31 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 33 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>;
>> };
>>
>> pcie_intc0: legacy-interrupt-controller {
>> interrupt-controller;
>> #interrupt-cells = <1>;
>> interrupt-parent = <&gic>;
>> interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 28 IRQ_TYPE_EDGE_RISING>,
>> <GIC_SPI 29 IRQ_TYPE_EDGE_RISING>;
>> };
>> };
>>
>>
>>>
>>>> However I can't get the Ethernet port functional.
>>>
>>>> Does this need MSI interrupt ?
>>>
>>> No.
>>
>> Does it also work with MSI?? Is there anything to be set in the driver
>> to request MSI interrupt?
>>
>>>
>>>> I can't see it has requested any.
>>>
>>> Yes, something went really, really wrong. See below.
>>>
>>> [...]
>>>> [ 2.303965] PCI host bridge /soc/pcie@21800000 ranges:
>>>> [ 2.309108] No bus range found for /soc/pcie@21800000, using [bus 00-ff]
>>>> [ 2.316269] IO 0x23250000..0x23253fff -> 0x00000000
>>>> [ 2.321499] MEM 0x50000000..0x5fffffff -> 0x50000000
>>>> [ 2.331666] keystone-pcie 21801000.pcie: PCI host bridge to bus 0000:00
>>>> [ 2.338283] pci_bus 0000:00: root bus resource [bus 00-ff]
>>>> [ 2.343937] pci_bus 0000:00: root bus resource [io 0x0000-0x3fff]
>>>> [ 2.350114] pci_bus 0000:00: root bus resource [mem 0x50000000-0x5fffffff]
>>>> [ 2.357095] pci 0000:00:00.0: [104c:b00b] type 01 class 0x060400
>>>> [ 2.357665] PCI: bus0: Fast back to back transfers disabled
>>>> [ 2.363717] pci 0000:01:00.0: [10ec:8168] type 00 class 0x020000
>>>> [ 2.363809] pci 0000:01:00.0: reg 0x10: [io 0x0000-0x00ff]
>>>> [ 2.363867] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x00000fff 64bit]
>>>> [ 2.363909] pci 0000:01:00.0: reg 0x20: [mem 0x00000000-0x0000ffff 64bit pref]
>>>> [ 2.363939] pci 0000:01:00.0: reg 0x30: [mem 0x00000000-0x0001ffff pref]
>>>> [ 2.364099] pci 0000:01:00.0: supports D1 D2
>>>> [ 2.364116] pci 0000:01:00.0: PME# supported from D0 D1 D2 D3hot D3cold
>>>> [ 2.381251] PCI: bus1: Fast back to back transfers disabled
>>>> [ 2.386989] pci 0000:00:00.0: BAR 8: assigned [mem 0x50000000-0x500fffff]
>>>> [ 2.393937] pci 0000:00:00.0: BAR 9: assigned [mem 0x50100000-0x501fffff pref]
>>>> [ 2.401221] pci 0000:00:00.0: BAR 7: assigned [io 0x1000-0x1fff]
>>>> [ 2.407320] pci 0000:01:00.0: BAR 6: assigned [mem 0x50100000-0x5011ffff pref]
>>>> [ 2.414597] pci 0000:01:00.0: BAR 4: assigned [mem 0x50120000-0x5012ffff 64bit pref]
>>>> [ 2.422380] pci 0000:01:00.0: BAR 2: assigned [mem 0x50000000-0x50000fff 64bit]
>>>> [ 2.429702] pci 0000:01:00.0: BAR 0: assigned [io 0x1000-0x10ff]
>>>> [ 2.435821] pci 0000:00:00.0: PCI bridge to [bus 01]
>>>> [ 2.440783] pci 0000:00:00.0: bridge window [io 0x1000-0x1fff]
>>>> [ 2.446896] pci 0000:00:00.0: bridge window [mem 0x50000000-0x500fffff]
>>>> [ 2.453699] pci 0000:00:00.0: bridge window [mem 0x50100000-0x501fffff pref]
>>>> [ 2.461453] pcieport 0000:00:00.0: Signaling PME through PCIe PME interrupt
>>>> [ 2.468411] pci 0000:01:00.0: Signaling PME through PCIe PME interrupt
>>>> [ 2.475075] pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme loaded
>>>> [ 2.475392] aer 0000:00:00.0:pcie02: service driver aer loaded
>>>> [ 2.475652] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
>>>> [ 2.481419] r8169 0000:01:00.0: enabling device (0140 -> 0143)
>>>> [ 2.488865] r8169 0000:01:00.0 eth0: RTL8169 at 0xf0d6a000, 00:00:00:00:00:00, XID 00000000 IRQ 286
>>>
>>> No need to go further, there is a serious problem here.
>>>
>>> Most of the XID bits are read from a mapped register. They're definitely not
>>> expected to be null as the driver requires it to identify a proper chipset
>>> (the common PCI configuration registers only tell that you aren't dealing
>>> with a coffee machine).
>>
>> Looks like during enumeration, the PCIe controller has correctly read the
>> Device ID a and Vendor ID over the PCIe bus. So the bus access is happening
>> at least to read the common PCI configuration space. But then what you are
>> confirming is the mapped XID register is not accessed correctly and is reading
>> zeors. Right? I will try to debug this first before proceeding any further.
>>
>
> One difference between the BAR logs w.r.t Marvel controller on K2E EVM is that
> the BARs are showing up as 64bit instead of 32bit.
>
> Marvell controller
> ==================
> [ 0.236353] pci 0000:00:00.0: BAR 8: assigned [mem 0x60000000-0x600fffff]
> [ 0.236364] pci 0000:00:00.0: BAR 9: assigned [mem 0x60100000-0x601fffff pref]
> [ 0.236373] pci 0000:00:00.0: BAR 7: assigned [io 0x1000-0x1fff]
> [ 0.236385] pci 0000:01:00.0: BAR 6: assigned [mem 0x60100000-0x6010ffff pref]
> [ 0.236394] pci 0000:01:00.0: BAR 5: assigned [mem 0x60000000-0x600001ff]
> [ 0.236406] pci 0000:01:00.0: BAR 4: assigned [io 0x1000-0x100f]
> [ 0.236418] pci 0000:01:00.0: BAR 0: assigned [io 0x1010-0x1017]
> [ 0.236429] pci 0000:01:00.0: BAR 2: assigned [io 0x1018-0x101f]
> [ 0.236441] pci 0000:01:00.0: BAR 1: assigned [io 0x1020-0x1023]
> [ 0.236452] pci 0000:01:00.0: BAR 3: assigned [io 0x1024-0x1027]
> [ 0.236464] pci 0000:00:00.0: PCI bridge to [bus 01]
> [ 0.236472] pci 0000:00:00.0: bridge window [io 0x1000-0x1fff]
> [ 0.236481] pci 0000:00:00.0: bridge window [mem 0x60000000-0x600fffff]
> [ 0.236490] pci 0000:00:00.0: bridge window [mem 0x60100000-0x601fffff pref]
>
> Realtek
> =========
> [ 2.311572] keystone-pcie 21801000.pcie: PCI host bridge to bus 0000:00
> [ 2.318188] pci_bus 0000:00: root bus resource [bus 00-ff]
> [ 2.323844] pci_bus 0000:00: root bus resource [io 0x0000-0x3fff]
> [ 2.330023] pci_bus 0000:00: root bus resource [mem 0x50000000-0x5fffffff]
> [ 2.337567] PCI: bus0: Fast back to back transfers disabled
> [ 2.361159] PCI: bus1: Fast back to back transfers disabled
> [ 2.366889] pci 0000:00:00.0: BAR 8: assigned [mem 0x50000000-0x500fffff]
> [ 2.373841] pci 0000:00:00.0: BAR 9: assigned [mem 0x50100000-0x501fffff pref]
> [ 2.381061] pci 0000:00:00.0: BAR 7: assigned [io 0x1000-0x1fff]
> [ 2.387225] pci 0000:01:00.0: BAR 6: assigned [mem 0x50100000-0x5011ffff pref]
> [ 2.394505] pci 0000:01:00.0: BAR 4: assigned [mem 0x50120000-0x5012ffff 64bit pref]
> [ 2.402288] pci 0000:01:00.0: BAR 2: assigned [mem 0x50000000-0x50000fff 64bit]
> [ 2.409610] pci 0000:01:00.0: BAR 0: assigned [io 0x1000-0x10ff]
> [ 2.415729] pci 0000:00:00.0: PCI bridge to [bus 01]
> [ 2.420693] pci 0000:00:00.0: bridge window [io 0x1000-0x1fff]
> [ 2.426806] pci 0000:00:00.0: bridge window [mem 0x50000000-0x500fffff]
> [ 2.433610] pci 0000:00:00.0: bridge window [mem 0x50100000-0x501fffff pref]
>
> Probably access to config space is happening in 64bit and it just get zeros?
> Trying to see how does PCI core determine if the access is 64bit. If you have a
> clue please let me know.
Francois,
Keystone PCI can't support 64bit BARs. Is there a Realtek NIC card I can purchase
that uses 32bit? Or Is there a way I can configure the driver to use 32bit BAR?
Murali
>
> Murali
>> Thanks.
>>
>> Murali
>>
>>> Any read returning zeroes would not surprize me.
>>>
>>> [...]
>>>> Can someone help me figure out what is missing ?
>>>
>>> Hardly at this point. I can only suggest to switch power off, plug
>>> the 8168 device in a x86 (32 or 64 bits) system and check how it behaves.
>>>
>> I need to continue work with my EVM as I have to make it functional.
>>
>>
>
>
--
Murali Karicheri
Linux Kernel, Keystone
^ permalink raw reply
* Re: [PATCH net-next v2 00/21] net: dsa: mv88e6xxx: turn into monolithic driver
From: Andrew Lunn @ 2016-05-09 17:56 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1462814578-6249-1-git-send-email-vivien.didelot@savoirfairelinux.com>
On Mon, May 09, 2016 at 01:22:37PM -0400, Vivien Didelot wrote:
> This patchset merges all mv88e6* drivers supported by the shared
> mv88e6xxx code into a single mv88e6xxx DSA switch driver.
>
> Some flags are added to describe the capabilities of a switch model,
> such as the presence of a PPU, EEPROM, some old or new registers, etc.
>
> First these flags are used to conditionally support the same set of
> functions in every driver, then specific driver files are removed in
> favor of the common mv88e6xxx driver.
>
> Only the merge of driver specific setup code assumes a few differences.
> If these differences such as frames priorities are really needed for
> some models, they can easily be brought back in a future patch.
>
> Some inconsistencies might show up, such as the need for
> MV88E6XXX_FLAG_PPU and MV88E6XXX_FLAG_PPU_ACTIVE flags. But this
> patchset does not aim to fix them yet. A future patch can do that if
> they end up being unwanted.
>
> The patchset has been tested on interconnected 88E6352 and 88E6185.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
I also tested v1, so
Tested-by: Andrew Lunn <andrew@lunn.ch>
Thanks
Andrew
^ permalink raw reply
* [PATCH v3 2/2] net: nps_enet: bug fix - handle lost tx interrupts
From: Elad Kanfi @ 2016-05-09 17:13 UTC (permalink / raw)
To: davem; +Cc: noamca, linux-kernel, abrodkin, eladkan, netdev
In-Reply-To: <1462814000-16331-1-git-send-email-eladkan@mellanox.com>
From: Elad Kanfi <eladkan@mellanox.com>
The tx interrupt is of edge type, and in case such interrupt is triggered
while it is masked it will not be handled even after tx interrupts are
re-enabled in the end of NAPI poll.
This will cause tx network to stop in the following scenario:
* Rx is being handled, hence interrupts are masked.
* Tx interrupt is triggered after checking if there is some tx to handle
and before re-enabling the interrupts.
In this situation only rx transaction will release tx requests.
In order to handle the tx that was missed( if there was one ),
a NAPI reschdule was added after enabling the interrupts.
Signed-off-by: Elad Kanfi <eladkan@mellanox.com>
Acked-by: Noam Camus <noamca@mellanox.com>
Acked-by: Gilad Ben-Yossef <giladby@mellanox.com>
---
drivers/net/ethernet/ezchip/nps_enet.c | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
index 25ac2de..085f912 100644
--- a/drivers/net/ethernet/ezchip/nps_enet.c
+++ b/drivers/net/ethernet/ezchip/nps_enet.c
@@ -183,6 +183,9 @@ static int nps_enet_poll(struct napi_struct *napi, int budget)
work_done = nps_enet_rx_handler(ndev);
if (work_done < budget) {
u32 buf_int_enable_value = 0;
+ u32 tx_ctrl_value = nps_enet_reg_get(priv, NPS_ENET_REG_TX_CTL);
+ u32 tx_ctrl_ct =
+ (tx_ctrl_value & TX_CTL_CT_MASK) >> TX_CTL_CT_SHIFT;
napi_complete(napi);
@@ -192,6 +195,18 @@ static int nps_enet_poll(struct napi_struct *napi, int budget)
nps_enet_reg_set(priv, NPS_ENET_REG_BUF_INT_ENABLE,
buf_int_enable_value);
+
+ /* in case we will get a tx interrupt while interrupts
+ * are masked, we will lose it since the tx is edge interrupt.
+ * specifically, while executing the code section above,
+ * between nps_enet_tx_handler and the interrupts enable, all
+ * tx requests will be stuck until we will get an rx interrupt.
+ * the two code lines below will solve this situation by
+ * re-adding ourselves to the poll list.
+ */
+
+ if (priv->tx_skb && !tx_ctrl_ct)
+ napi_reschedule(napi);
}
return work_done;
--
1.7.1
^ permalink raw reply related
* Re: [PATCH v2 net-next] ifb: support more features
From: Eric Dumazet @ 2016-05-09 17:41 UTC (permalink / raw)
To: Alexander Duyck
Cc: David Miller, Vlad Yasevich, Alexander Duyck, netdev, Tom Herbert
In-Reply-To: <1462815597.23934.35.camel@edumazet-glaptop3.roam.corp.google.com>
On Mon, 2016-05-09 at 10:39 -0700, Eric Dumazet wrote:
> On Mon, 2016-05-09 at 10:22 -0700, Alexander Duyck wrote:
>
> > One thought that just occurred to me based on this would be to
> > configure inner headers on the way up, and to configure the outer
> > headers on the way down. Then that way we could go through and be
> > guaranteed that the inner headers represent the inner most set of
> > header offsets, and the outer ones represent the outer-most set
> > regardless of the total number of headers present and there would be
> > no need to call into the reset_headers function since all the headers
> > would already be set.
> >
> > I was also looking at possibly dropping the inner transport offset as
> > from what I can tell it and the csum_offset should always be the same
> > value since csum_offset will always point to the inner transport
> > header when any kind of offload is enabled which is the criteria for
> > skb->encapsulation being set anyway.
>
> Ideally nothing should be changed in the source skb while doing
> gso_segment() calls.
>
> As we did in gro_complete() when adding nhoff argument, we probably
> could pass the current offset and not touch skb->data and various header
> offsets.
Ugly things like skb_gso_error_unwind() would then disappear.
What a mess it is.
^ permalink raw reply
* Re: [PATCH v2 net-next] ifb: support more features
From: Eric Dumazet @ 2016-05-09 17:39 UTC (permalink / raw)
To: Alexander Duyck
Cc: David Miller, Vlad Yasevich, Alexander Duyck, netdev, Tom Herbert
In-Reply-To: <CAKgT0UffTCeUn5jqFYNqtE6g25sdcAvT6hLNG1F=0BKRWd-xWA@mail.gmail.com>
On Mon, 2016-05-09 at 10:22 -0700, Alexander Duyck wrote:
> One thought that just occurred to me based on this would be to
> configure inner headers on the way up, and to configure the outer
> headers on the way down. Then that way we could go through and be
> guaranteed that the inner headers represent the inner most set of
> header offsets, and the outer ones represent the outer-most set
> regardless of the total number of headers present and there would be
> no need to call into the reset_headers function since all the headers
> would already be set.
>
> I was also looking at possibly dropping the inner transport offset as
> from what I can tell it and the csum_offset should always be the same
> value since csum_offset will always point to the inner transport
> header when any kind of offload is enabled which is the criteria for
> skb->encapsulation being set anyway.
Ideally nothing should be changed in the source skb while doing
gso_segment() calls.
As we did in gro_complete() when adding nhoff argument, we probably
could pass the current offset and not touch skb->data and various header
offsets.
Presumably gso state should be stored in a separate structure.
I meant, gso_segment() is not a 'please sanity fix this skb'.
Only DODGY thing might need to ?
^ permalink raw reply
* Re: [PATCH v3 net-next 00/11] ipv6: Enable GUEoIPv6 and more fixes for v6 tunneling
From: Alexander Duyck @ 2016-05-09 17:32 UTC (permalink / raw)
To: Tom Herbert; +Cc: David Miller, Netdev, Kernel Team
In-Reply-To: <CALx6S34QeJpb4MocpDN_0XuvV4fxN25yO7-SjYBNta5ALzoDSw@mail.gmail.com>
On Mon, May 9, 2016 at 9:56 AM, Tom Herbert <tom@herbertland.com> wrote:
> On Fri, May 6, 2016 at 8:03 PM, Alexander Duyck
> <alexander.duyck@gmail.com> wrote:
>> On Fri, May 6, 2016 at 7:11 PM, Tom Herbert <tom@herbertland.com> wrote:
>>> On Fri, May 6, 2016 at 7:03 PM, Alexander Duyck
>>> <alexander.duyck@gmail.com> wrote:
>>>> On Fri, May 6, 2016 at 6:57 PM, Tom Herbert <tom@herbertland.com> wrote:
>>>>> On Fri, May 6, 2016 at 6:09 PM, Alexander Duyck
>>>>> <alexander.duyck@gmail.com> wrote:
>>>>>> On Fri, May 6, 2016 at 3:11 PM, Tom Herbert <tom@herbertland.com> wrote:
>>>>>>> This patch set:
>>>>>>> - Fixes GRE6 to process translate flags correctly from configuration
>>>>>>> - Adds support for GSO and GRO for ip6ip6 and ip4ip6
>>>>>>> - Add support for FOU and GUE in IPv6
>>>>>>> - Support GRE, ip6ip6 and ip4ip6 over FOU/GUE
>>>>>>> - Fixes ip6_input to deal with UDP encapsulations
>>>>>>> - Some other minor fixes
>>>>>>>
>>>>>>> v2:
>>>>>>> - Removed a check of GSO types in MPLS
>>>>>>> - Define GSO type SKB_GSO_IPXIP6 and SKB_GSO_IPXIP4 (based on input
>>>>>>> from Alexander)
>>>>>>> - Don't define GSO types specifally for IP6IP6 and IP4IP6, above
>>>>>>> fix makes that uncessary
>>>>>>> - Don't bother clearing encapsulation flag in UDP tunnel segment
>>>>>>> (another item suggested by Alexander).
>>>>>>>
>>>>>>> v3:
>>>>>>> - Address some minor comments from Alexander
>>>>>>>
>>>>>>> Tested:
>>>>>>> Tested a variety of case, but not the full matrix (which is quite
>>>>>>> large now). Most of the obivous cases (e.g. GRE) work fine. Still
>>>>>>> some issues probably with GSO/GRO being effective in all cases.
>>>>>>>
>>>>>>> - IPv4/GRE/GUE/IPv6 with RCO
>>>>>>> 1 TCP_STREAM
>>>>>>> 6616 Mbps
>>>>>>> 200 TCP_RR
>>>>>>> 1244043 tps
>>>>>>> 141/243/446 90/95/99% latencies
>>>>>>> 86.61% CPU utilization
>>>>>>> - IPv6/GRE/GUE/IPv6 with RCO
>>>>>>> 1 TCP_STREAM
>>>>>>> 6940 Mbps
>>>>>>> 200 TCP_RR
>>>>>>> 1270903 tps
>>>>>>> 138/236/440 90/95/99% latencies
>>>>>>> 87.51% CPU utilization
>>>>>>>
>>>>>>> - IP6IP6
>>>>>>> 1 TCP_STREAM
>>>>>>> 2576 Mbps
>>>>>>> 200 TCP_RR
>>>>>>> 498981 tps
>>>>>>> 388/498/631 90/95/99% latencies
>>>>>>> 19.75% CPU utilization (1 CPU saturated)
>>>>>>>
>>>>>>> - IP6IP6/GUE/IPv6 with RCO
>>>>>>> 1 TCP_STREAM
>>>>>>> 1854 Mbps
>>>>>>> 200 TCP_RR
>>>>>>> 1233818 tps
>>>>>>> 143/244/451 90/95/99% latencies
>>>>>>> 87.57 CPU utilization
>>>>>>>
>>>>>>> - IP4IP6
>>>>>>> 1 TCP_STREAM
>>>>>>> 200 TCP_RR
>>>>>>> 763774 tps
>>>>>>> 250/318/466 90/95/99% latencies
>>>>>>> 35.25% CPU utilization (1 CPU saturated)
>>>>>>>
>>>>>>> - GRE with keyid
>>>>>>> 200 TCP_RR
>>>>>>> 744173 tps
>>>>>>> 258/332/461 90/95/99% latencies
>>>>>>> 34.59% CPU utilization (1 CPU saturated)
>>>>>>
>>>>>> So I tried testing your patch set and it looks like I cannot get GRE
>>>>>> working for any netperf test. If I pop the patches off it is even
>>>>>> worse since it looks like patch 3 fixes some tunnel flags issues, but
>>>>>> still doesn't resolve all the issues introduced with b05229f44228
>>>>>> ("gre6: Cleanup GREv6 transmit path, call common GRE functions").
>>>>>> Reverting the entire patch seems to resolve the issues, but I will try
>>>>>> to pick it apart tonight to see if I can find the other issues that
>>>>>> weren't addressed in this patch series.
>>>>>>
>>>>>
>>>>> Can you give details about configuration, test you're running, and HW?
>>>>
>>>> The issue looks like it may be specific to ip6gretap. I'm running the
>>>> test over an i40e adapter, but it shouldn't make much difference. I'm
>>>> thinking it may have something to do with the MTU configuration as
>>>> that is one of the things I am noticing has changed between the
>>>> working and the broken version of the code.
>>>>
>>> I'm not seeing any issue with configuring:
>>>
>>> ip link add name tun8 type ip6gretap remote
>>> 2401:db00:20:911a:face:0:27:0 local 2401:db00:20:911a:face:0:25:0 ttl
>>> 225
>>>
>>> MTU issues would not surprise me with IPv6 though. This is part of the
>>> area of code that seems drastically different than what IPv4 is doing.
>>
>> I am also using a key.
>>
>> ip link add $name type ip6gretap key $net \
>> local fec0::1 remote $addr6 ttl 225 dev $PF0
>>
> I don't see any issue with key enabled.
>
>> Does the device you are using support any kind of checksum offload for
>> inner headers on GRE tunnels? It looks like if I turn off checksums
>
> I don't believe so.
>
>> and correct the MTU I can then send traffic without issues. I'd say
>> that the Tx cleanup probably introduced 3 regressions. The first one
>> you addressed in patch 3 which fixes the flags. The second being the
>> fact that the MTU is wrong, and the third being something that
>> apparently broke checksum and maybe segmentation offload for
>> ip6gretap.
>>
> The MTU can be set in place in IPv6 code that doesn't exist in Ipv4. I
> am especially wondering about the "if (p->flags & IP6_TNL_F_CAP_XMIT)"
> block.
>
>> Really I think the transmit path cleanup should have probably been
>> broken down into a set of patches rather than slamming it in all in
>> one block. I can spend some time next week trying to sort it out if
>> you don't have any hardware that supports GRE segmentation or checksum
>> offload. If worse comes to worse I will just try breaking the revert
>> down into a set of smaller patches so I can figure out exactly which
>> change broke things.
>>
> I am still trying to reproduce.
What NICs are you testing with? Depending on the NIC I might be able
to point you in the direction of something that can reproduce the
issue.
At this point I am thinking it is an issue with a header offset since
I believe GSO resets all that and probably corrects the issue.
Thanks.
- Alex
^ permalink raw reply
* Re: rtk8168 driver help needed
From: Murali Karicheri @ 2016-05-09 17:25 UTC (permalink / raw)
To: Francois Romieu; +Cc: open list:TI NETCP ETHERNET DRIVER
In-Reply-To: <5730A4B0.7000606@ti.com>
On 05/09/2016 10:54 AM, Murali Karicheri wrote:
> Francois,
>
> Thanks for responding.
>
> On 05/07/2016 04:35 AM, Francois Romieu wrote:
>> Murali Karicheri <m-karicheri2@ti.com> :
>> [...]
>>> I am trying to integrate the rtl8168 PCIe card to have Ethernet functional
>>> on my Keystone EVM.
>>
>> Which (EVM) one ?
> K2G EVM. This is a new EVM for which work has been started to add it to upstream
> kernel. But it not there yet. The PCIe h/w in the K2G SoC is a re-use from
> existing SoC such as K2E. The PCIe controller (Root complex a.k.a RC) driver
> based on this PCIe h/w works fine on K2E EVM with a Marvel SATA controller
> connected to the PCIe port. On K2G EVM, I have a PCIe slot to which I have
> plugged the rtl8168 PCIe card and power on with the log I had sent you. The
> serdes driver is responsible for link setup seems to work fine, link is up and
> could detect the rtl8168 below.
>>
>>> I purchased the rtl8111c Gib card from Amazon. The Card is detected
>>> by the RC and I can see it is enumerated and show up when doing lspci command.
>>
>> What does "the RC" mean ? A different PC ?
>
> RC - Root Complex (PCIe controller - drivers/pci/host/pci-keystone.c, a designware
> based PCIe controller driver)
>
> The the PCIe controller driver bindings...
>
> pcie0_phy: phy@2320000 {
> #phy-cells = <0>;
> compatible = "ti,keystone-serdes-pcie";
> reg = <0x02320000 0x4000>;
> link-rate-kbps = <5000000>;
> num-lanes = <1>;
> status = "disabled";
> };
>
> pcie0: pcie@21800000 {
> compatible = "ti,keystone-pcie", "snps,dw-pcie";
> power-domains = <&k2g_pds K2G_DEV_PCIE0>;
> clocks = <&k2g_clks K2G_DEV_PCIE0 K2G_DEV_PCIE_VBUS_CLK>;
> clock-names = "pcie";
> #address-cells = <3>;
> #size-cells = <2>;
> reg = <0x21801000 0x2000>, <0x21800000 0x1000>, <0x02620128 4>;
> ranges = <0x81000000 0 0 0x23250000 0 0x4000
> 0x82000000 0 0x50000000 0x50000000 0 0x10000000>;
>
> status = "disabled";
> device_type = "pci";
> num-lanes = <1>;
> phys = <&pcie0_phy>;
>
> #interrupt-cells = <1>;
> interrupt-map-mask = <0 0 0 7>;
> interrupt-map = <0 0 0 1 &pcie_intc0 0>, /* INT A */
> <0 0 0 2 &pcie_intc0 1>, /* INT B */
> <0 0 0 3 &pcie_intc0 2>, /* INT C */
> <0 0 0 4 &pcie_intc0 3>; /* INT D */
> pcie_msi_intc0: msi-interrupt-controller {
> interrupt-controller;
> #interrupt-cells = <1>;
> interrupt-parent = <&gic>;
> interrupts = <GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 31 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 33 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>;
> };
>
> pcie_intc0: legacy-interrupt-controller {
> interrupt-controller;
> #interrupt-cells = <1>;
> interrupt-parent = <&gic>;
> interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 27 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 28 IRQ_TYPE_EDGE_RISING>,
> <GIC_SPI 29 IRQ_TYPE_EDGE_RISING>;
> };
> };
>
>
>>
>>> However I can't get the Ethernet port functional.
>>
>>> Does this need MSI interrupt ?
>>
>> No.
>
> Does it also work with MSI?? Is there anything to be set in the driver
> to request MSI interrupt?
>
>>
>>> I can't see it has requested any.
>>
>> Yes, something went really, really wrong. See below.
>>
>> [...]
>>> [ 2.303965] PCI host bridge /soc/pcie@21800000 ranges:
>>> [ 2.309108] No bus range found for /soc/pcie@21800000, using [bus 00-ff]
>>> [ 2.316269] IO 0x23250000..0x23253fff -> 0x00000000
>>> [ 2.321499] MEM 0x50000000..0x5fffffff -> 0x50000000
>>> [ 2.331666] keystone-pcie 21801000.pcie: PCI host bridge to bus 0000:00
>>> [ 2.338283] pci_bus 0000:00: root bus resource [bus 00-ff]
>>> [ 2.343937] pci_bus 0000:00: root bus resource [io 0x0000-0x3fff]
>>> [ 2.350114] pci_bus 0000:00: root bus resource [mem 0x50000000-0x5fffffff]
>>> [ 2.357095] pci 0000:00:00.0: [104c:b00b] type 01 class 0x060400
>>> [ 2.357665] PCI: bus0: Fast back to back transfers disabled
>>> [ 2.363717] pci 0000:01:00.0: [10ec:8168] type 00 class 0x020000
>>> [ 2.363809] pci 0000:01:00.0: reg 0x10: [io 0x0000-0x00ff]
>>> [ 2.363867] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x00000fff 64bit]
>>> [ 2.363909] pci 0000:01:00.0: reg 0x20: [mem 0x00000000-0x0000ffff 64bit pref]
>>> [ 2.363939] pci 0000:01:00.0: reg 0x30: [mem 0x00000000-0x0001ffff pref]
>>> [ 2.364099] pci 0000:01:00.0: supports D1 D2
>>> [ 2.364116] pci 0000:01:00.0: PME# supported from D0 D1 D2 D3hot D3cold
>>> [ 2.381251] PCI: bus1: Fast back to back transfers disabled
>>> [ 2.386989] pci 0000:00:00.0: BAR 8: assigned [mem 0x50000000-0x500fffff]
>>> [ 2.393937] pci 0000:00:00.0: BAR 9: assigned [mem 0x50100000-0x501fffff pref]
>>> [ 2.401221] pci 0000:00:00.0: BAR 7: assigned [io 0x1000-0x1fff]
>>> [ 2.407320] pci 0000:01:00.0: BAR 6: assigned [mem 0x50100000-0x5011ffff pref]
>>> [ 2.414597] pci 0000:01:00.0: BAR 4: assigned [mem 0x50120000-0x5012ffff 64bit pref]
>>> [ 2.422380] pci 0000:01:00.0: BAR 2: assigned [mem 0x50000000-0x50000fff 64bit]
>>> [ 2.429702] pci 0000:01:00.0: BAR 0: assigned [io 0x1000-0x10ff]
>>> [ 2.435821] pci 0000:00:00.0: PCI bridge to [bus 01]
>>> [ 2.440783] pci 0000:00:00.0: bridge window [io 0x1000-0x1fff]
>>> [ 2.446896] pci 0000:00:00.0: bridge window [mem 0x50000000-0x500fffff]
>>> [ 2.453699] pci 0000:00:00.0: bridge window [mem 0x50100000-0x501fffff pref]
>>> [ 2.461453] pcieport 0000:00:00.0: Signaling PME through PCIe PME interrupt
>>> [ 2.468411] pci 0000:01:00.0: Signaling PME through PCIe PME interrupt
>>> [ 2.475075] pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme loaded
>>> [ 2.475392] aer 0000:00:00.0:pcie02: service driver aer loaded
>>> [ 2.475652] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
>>> [ 2.481419] r8169 0000:01:00.0: enabling device (0140 -> 0143)
>>> [ 2.488865] r8169 0000:01:00.0 eth0: RTL8169 at 0xf0d6a000, 00:00:00:00:00:00, XID 00000000 IRQ 286
>>
>> No need to go further, there is a serious problem here.
>>
>> Most of the XID bits are read from a mapped register. They're definitely not
>> expected to be null as the driver requires it to identify a proper chipset
>> (the common PCI configuration registers only tell that you aren't dealing
>> with a coffee machine).
>
> Looks like during enumeration, the PCIe controller has correctly read the
> Device ID a and Vendor ID over the PCIe bus. So the bus access is happening
> at least to read the common PCI configuration space. But then what you are
> confirming is the mapped XID register is not accessed correctly and is reading
> zeors. Right? I will try to debug this first before proceeding any further.
>
One difference between the BAR logs w.r.t Marvel controller on K2E EVM is that
the BARs are showing up as 64bit instead of 32bit.
Marvell controller
==================
[ 0.236353] pci 0000:00:00.0: BAR 8: assigned [mem 0x60000000-0x600fffff]
[ 0.236364] pci 0000:00:00.0: BAR 9: assigned [mem 0x60100000-0x601fffff pref]
[ 0.236373] pci 0000:00:00.0: BAR 7: assigned [io 0x1000-0x1fff]
[ 0.236385] pci 0000:01:00.0: BAR 6: assigned [mem 0x60100000-0x6010ffff pref]
[ 0.236394] pci 0000:01:00.0: BAR 5: assigned [mem 0x60000000-0x600001ff]
[ 0.236406] pci 0000:01:00.0: BAR 4: assigned [io 0x1000-0x100f]
[ 0.236418] pci 0000:01:00.0: BAR 0: assigned [io 0x1010-0x1017]
[ 0.236429] pci 0000:01:00.0: BAR 2: assigned [io 0x1018-0x101f]
[ 0.236441] pci 0000:01:00.0: BAR 1: assigned [io 0x1020-0x1023]
[ 0.236452] pci 0000:01:00.0: BAR 3: assigned [io 0x1024-0x1027]
[ 0.236464] pci 0000:00:00.0: PCI bridge to [bus 01]
[ 0.236472] pci 0000:00:00.0: bridge window [io 0x1000-0x1fff]
[ 0.236481] pci 0000:00:00.0: bridge window [mem 0x60000000-0x600fffff]
[ 0.236490] pci 0000:00:00.0: bridge window [mem 0x60100000-0x601fffff pref]
Realtek
=========
[ 2.311572] keystone-pcie 21801000.pcie: PCI host bridge to bus 0000:00
[ 2.318188] pci_bus 0000:00: root bus resource [bus 00-ff]
[ 2.323844] pci_bus 0000:00: root bus resource [io 0x0000-0x3fff]
[ 2.330023] pci_bus 0000:00: root bus resource [mem 0x50000000-0x5fffffff]
[ 2.337567] PCI: bus0: Fast back to back transfers disabled
[ 2.361159] PCI: bus1: Fast back to back transfers disabled
[ 2.366889] pci 0000:00:00.0: BAR 8: assigned [mem 0x50000000-0x500fffff]
[ 2.373841] pci 0000:00:00.0: BAR 9: assigned [mem 0x50100000-0x501fffff pref]
[ 2.381061] pci 0000:00:00.0: BAR 7: assigned [io 0x1000-0x1fff]
[ 2.387225] pci 0000:01:00.0: BAR 6: assigned [mem 0x50100000-0x5011ffff pref]
[ 2.394505] pci 0000:01:00.0: BAR 4: assigned [mem 0x50120000-0x5012ffff 64bit pref]
[ 2.402288] pci 0000:01:00.0: BAR 2: assigned [mem 0x50000000-0x50000fff 64bit]
[ 2.409610] pci 0000:01:00.0: BAR 0: assigned [io 0x1000-0x10ff]
[ 2.415729] pci 0000:00:00.0: PCI bridge to [bus 01]
[ 2.420693] pci 0000:00:00.0: bridge window [io 0x1000-0x1fff]
[ 2.426806] pci 0000:00:00.0: bridge window [mem 0x50000000-0x500fffff]
[ 2.433610] pci 0000:00:00.0: bridge window [mem 0x50100000-0x501fffff pref]
Probably access to config space is happening in 64bit and it just get zeros?
Trying to see how does PCI core determine if the access is 64bit. If you have a
clue please let me know.
Murali
> Thanks.
>
> Murali
>
>> Any read returning zeroes would not surprize me.
>>
>> [...]
>>> Can someone help me figure out what is missing ?
>>
>> Hardly at this point. I can only suggest to switch power off, plug
>> the 8168 device in a x86 (32 or 64 bits) system and check how it behaves.
>>
> I need to continue work with my EVM as I have to make it functional.
>
>
--
Murali Karicheri
Linux Kernel, Keystone
^ permalink raw reply
* [PATCH net-next v2 20/21] net: dsa: mv88e6131: use EDSA tag protocol
From: Vivien Didelot @ 2016-05-09 17:22 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1462814578-6249-1-git-send-email-vivien.didelot@savoirfairelinux.com>
6131 is the only driver to set the tag protocol to DSA_TAG_PROTO_DSA.
Since it works fine with DSA_TAG_PROTO_EDSA, change its value, like all
other mv88e6xxx drivers.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/Kconfig | 2 +-
drivers/net/dsa/mv88e6131.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 4aaadce..7e01dce 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -17,7 +17,7 @@ config NET_DSA_MV88E6131
tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support"
depends on NET_DSA
select NET_DSA_MV88E6XXX
- select NET_DSA_TAG_DSA
+ select NET_DSA_TAG_EDSA
---help---
This enables support for the Marvell 88E6085/6095/6095F/6131
ethernet switch chips.
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 22952be..bbad199 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -59,7 +59,7 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev,
}
struct dsa_switch_driver mv88e6131_switch_driver = {
- .tag_protocol = DSA_TAG_PROTO_DSA,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.probe = mv88e6131_drv_probe,
.setup = mv88e6xxx_setup,
.set_addr = mv88e6xxx_set_addr,
--
2.8.2
^ permalink raw reply related
* [PATCH net-next v2 17/21] net: dsa: mv88e6xxx: factorize GLOBAL_CONTROL_2 setup
From: Vivien Didelot @ 2016-05-09 17:22 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1462814578-6249-1-git-send-email-vivien.didelot@savoirfairelinux.com>
All switch models setup the GLOBAL_CONTROL_2 register with slightly
differences.
Since the cascade mode is valid even in a single chip setup, factorize
such configuration.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 15 ---------------
drivers/net/dsa/mv88e6131.c | 16 ----------------
drivers/net/dsa/mv88e6171.c | 15 ---------------
drivers/net/dsa/mv88e6352.c | 14 --------------
drivers/net/dsa/mv88e6xxx.c | 7 +++++++
5 files changed, 7 insertions(+), 60 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 5df06d8..8f3a7c5 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -51,17 +51,6 @@ static const char *mv88e6123_drv_probe(struct device *dsa_dev,
ARRAY_SIZE(mv88e6123_table));
}
-static int mv88e6123_setup_global(struct dsa_switch *ds)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
- /* Disable remote management for now, and set the switch's
- * DSA device number.
- */
- return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
- ds->index & 0x1f);
-}
-
static int mv88e6123_setup(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -73,10 +62,6 @@ static int mv88e6123_setup(struct dsa_switch *ds)
if (ret < 0)
return ret;
- ret = mv88e6123_setup_global(ds);
- if (ret < 0)
- return ret;
-
return mv88e6xxx_setup_ports(ds);
}
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index c8e3974..b6ca07b 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -61,22 +61,6 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev,
static int mv88e6131_setup_global(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- int ret;
-
- /* Disable cascade port functionality unless this device
- * is used in a cascade configuration, and set the switch's
- * DSA device number.
- */
- if (ds->dst->pd->nr_chips > 1)
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
- GLOBAL_CONTROL_2_MULTIPLE_CASCADE |
- (ds->index & 0x1f));
- else
- ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
- GLOBAL_CONTROL_2_NO_CASCADE |
- (ds->index & 0x1f));
- if (ret)
- return ret;
/* Force the priority of IGMP/MLD snoop frames and ARP frames
* to the highest setting.
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index a848aef..83678ad 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -58,17 +58,6 @@ static const char *mv88e6171_drv_probe(struct device *dsa_dev,
ARRAY_SIZE(mv88e6171_table));
}
-static int mv88e6171_setup_global(struct dsa_switch *ds)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
- /* Disable remote management for now, and set the switch's
- * DSA device number.
- */
- return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
- ds->index & 0x1f);
-}
-
static int mv88e6171_setup(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -80,10 +69,6 @@ static int mv88e6171_setup(struct dsa_switch *ds)
if (ret < 0)
return ret;
- ret = mv88e6171_setup_global(ds);
- if (ret < 0)
- return ret;
-
return mv88e6xxx_setup_ports(ds);
}
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index e098870..81810dd 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -77,16 +77,6 @@ static const char *mv88e6352_drv_probe(struct device *dsa_dev,
ARRAY_SIZE(mv88e6352_table));
}
-static int mv88e6352_setup_global(struct dsa_switch *ds)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
- /* Disable remote management for now, and set the switch's
- * DSA device number.
- */
- return mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x1c, ds->index & 0x1f);
-}
-
static int mv88e6352_setup(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -98,10 +88,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
if (ret < 0)
return ret;
- ret = mv88e6352_setup_global(ds);
- if (ret < 0)
- return ret;
-
return mv88e6xxx_setup_ports(ds);
}
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 27551c1..d8bb4c8 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2950,6 +2950,13 @@ static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
if (err)
return err;
+ /* Disable remote management, and set the switch's DSA device number. */
+ err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2,
+ GLOBAL_CONTROL_2_MULTIPLE_CASCADE |
+ (ds->index & 0x1f));
+ if (err)
+ return err;
+
/* Set the default address aging time to 5 minutes, and
* enable address learn messages to be sent to all message
* ports.
--
2.8.2
^ permalink raw reply related
* [PATCH net-next v2 21/21] net: dsa: mv88e6xxx: factorize the switch driver
From: Vivien Didelot @ 2016-05-09 17:22 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1462814578-6249-1-git-send-email-vivien.didelot@savoirfairelinux.com>
Now that all drivers support the same set of functions and the same
setup code, drop every model-specific DSA switch driver and replace them
with a common mv88e6xxx driver.
This merges the info tables into one, removes the function exports, the
model-specific files, and update the defconfigs.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
arch/arm/configs/multi_v5_defconfig | 5 +-
arch/arm/configs/mvebu_v7_defconfig | 2 +-
arch/arm/configs/orion5x_defconfig | 3 +-
arch/tile/configs/tilegx_defconfig | 3 +-
arch/tile/configs/tilepro_defconfig | 3 +-
drivers/net/dsa/Kconfig | 40 +---
drivers/net/dsa/Makefile | 15 +-
drivers/net/dsa/mv88e6123.c | 93 ----------
drivers/net/dsa/mv88e6131.c | 101 ----------
drivers/net/dsa/mv88e6171.c | 101 ----------
drivers/net/dsa/mv88e6352.c | 121 ------------
drivers/net/dsa/mv88e6xxx.c | 354 +++++++++++++++++++++++++++---------
drivers/net/dsa/mv88e6xxx.h | 91 +++------
13 files changed, 302 insertions(+), 630 deletions(-)
delete mode 100644 drivers/net/dsa/mv88e6123.c
delete mode 100644 drivers/net/dsa/mv88e6131.c
delete mode 100644 drivers/net/dsa/mv88e6171.c
delete mode 100644 drivers/net/dsa/mv88e6352.c
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig
index e11d99d..690352d 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -91,10 +91,7 @@ CONFIG_SATA_AHCI=y
CONFIG_SATA_MV=y
CONFIG_NETDEVICES=y
CONFIG_NET_DSA_MV88E6060=y
-CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123=y
-CONFIG_NET_DSA_MV88E6171=y
-CONFIG_NET_DSA_MV88E6352=y
+CONFIG_NET_DSA_MV88E6XXX=y
CONFIG_MV643XX_ETH=y
CONFIG_R8169=y
CONFIG_MARVELL_PHY=y
diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
index dc5797a..6492407 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -66,7 +66,7 @@ CONFIG_SATA_AHCI=y
CONFIG_AHCI_MVEBU=y
CONFIG_SATA_MV=y
CONFIG_NETDEVICES=y
-CONFIG_NET_DSA_MV88E6171=y
+CONFIG_NET_DSA_MV88E6XXX=y
CONFIG_MV643XX_ETH=y
CONFIG_MVNETA=y
CONFIG_MVPP2=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 6a5bc27..27a70a7 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -85,8 +85,7 @@ CONFIG_ATA=y
CONFIG_SATA_MV=y
CONFIG_NETDEVICES=y
CONFIG_MII=y
-CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123=y
+CONFIG_NET_DSA_MV88E6XXX=y
CONFIG_MV643XX_ETH=y
CONFIG_MARVELL_PHY=y
# CONFIG_INPUT_MOUSEDEV is not set
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig
index 3f3dfb8..7189055 100644
--- a/arch/tile/configs/tilegx_defconfig
+++ b/arch/tile/configs/tilegx_defconfig
@@ -221,8 +221,7 @@ CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_TUN=y
CONFIG_VETH=m
CONFIG_NET_DSA_MV88E6060=y
-CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123=y
+CONFIG_NET_DSA_MV88E6XXX=y
CONFIG_SKY2=y
CONFIG_PTP_1588_CLOCK_TILEGX=y
# CONFIG_WLAN is not set
diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig
index ef9e27e..dc85468 100644
--- a/arch/tile/configs/tilepro_defconfig
+++ b/arch/tile/configs/tilepro_defconfig
@@ -340,8 +340,7 @@ CONFIG_NETCONSOLE_DYNAMIC=y
CONFIG_TUN=y
CONFIG_VETH=m
CONFIG_NET_DSA_MV88E6060=y
-CONFIG_NET_DSA_MV88E6131=y
-CONFIG_NET_DSA_MV88E6123=y
+CONFIG_NET_DSA_MV88E6XXX=y
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_E1000E=y
# CONFIG_WLAN is not set
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 7e01dce..200663c 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -1,10 +1,6 @@
menu "Distributed Switch Architecture drivers"
depends on HAVE_NET_DSA
-config NET_DSA_MV88E6XXX
- tristate
- default n
-
config NET_DSA_MV88E6060
tristate "Marvell 88E6060 ethernet switch chip support"
depends on NET_DSA
@@ -13,41 +9,13 @@ config NET_DSA_MV88E6060
This enables support for the Marvell 88E6060 ethernet switch
chip.
-config NET_DSA_MV88E6131
- tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support"
- depends on NET_DSA
- select NET_DSA_MV88E6XXX
- select NET_DSA_TAG_EDSA
- ---help---
- This enables support for the Marvell 88E6085/6095/6095F/6131
- ethernet switch chips.
-
-config NET_DSA_MV88E6123
- tristate "Marvell 88E6123/6161/6165 ethernet switch chip support"
- depends on NET_DSA
- select NET_DSA_MV88E6XXX
- select NET_DSA_TAG_EDSA
- ---help---
- This enables support for the Marvell 88E6123/6161/6165
- ethernet switch chips.
-
-config NET_DSA_MV88E6171
- tristate "Marvell 88E6171/6175/6350/6351 ethernet switch chip support"
- depends on NET_DSA
- select NET_DSA_MV88E6XXX
- select NET_DSA_TAG_EDSA
- ---help---
- This enables support for the Marvell 88E6171/6175/6350/6351
- ethernet switches chips.
-
-config NET_DSA_MV88E6352
- tristate "Marvell 88E6172/6176/6320/6321/6352 ethernet switch chip support"
+config NET_DSA_MV88E6XXX
+ tristate "Marvell 88E6xxx Ethernet switch chip support"
depends on NET_DSA
- select NET_DSA_MV88E6XXX
select NET_DSA_TAG_EDSA
---help---
- This enables support for the Marvell 88E6172, 88E6176, 88E6320,
- 88E6321 and 88E6352 ethernet switch chips.
+ This enables support for most of the Marvell 88E6xxx models of
+ Ethernet switch chips, except 88E6060.
config NET_DSA_BCM_SF2
tristate "Broadcom Starfighter 2 Ethernet switch support"
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index a6e0993..76b751d 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -1,16 +1,3 @@
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
-obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx_drv.o
-mv88e6xxx_drv-y += mv88e6xxx.o
-ifdef CONFIG_NET_DSA_MV88E6123
-mv88e6xxx_drv-y += mv88e6123.o
-endif
-ifdef CONFIG_NET_DSA_MV88E6131
-mv88e6xxx_drv-y += mv88e6131.o
-endif
-ifdef CONFIG_NET_DSA_MV88E6352
-mv88e6xxx_drv-y += mv88e6352.o
-endif
-ifdef CONFIG_NET_DSA_MV88E6171
-mv88e6xxx_drv-y += mv88e6171.o
-endif
+obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o
obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm_sf2.o
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
deleted file mode 100644
index 2bc407b..0000000
--- a/drivers/net/dsa/mv88e6123.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support
- * Copyright (c) 2008-2009 Marvell Semiconductor
- *
- * This program 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.
- */
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-#include <net/dsa.h>
-#include "mv88e6xxx.h"
-
-static const struct mv88e6xxx_info mv88e6123_table[] = {
- {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
- .family = MV88E6XXX_FAMILY_6165,
- .name = "Marvell 88E6123",
- .num_databases = 4096,
- .num_ports = 3,
- .flags = MV88E6XXX_FLAGS_FAMILY_6165,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
- .family = MV88E6XXX_FAMILY_6165,
- .name = "Marvell 88E6161",
- .num_databases = 4096,
- .num_ports = 6,
- .flags = MV88E6XXX_FLAGS_FAMILY_6165,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
- .family = MV88E6XXX_FAMILY_6165,
- .name = "Marvell 88E6165",
- .num_databases = 4096,
- .num_ports = 6,
- .flags = MV88E6XXX_FLAGS_FAMILY_6165,
- }
-};
-
-static const char *mv88e6123_drv_probe(struct device *dsa_dev,
- struct device *host_dev, int sw_addr,
- void **priv)
-{
- return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
- mv88e6123_table,
- ARRAY_SIZE(mv88e6123_table));
-}
-
-struct dsa_switch_driver mv88e6123_switch_driver = {
- .tag_protocol = DSA_TAG_PROTO_EDSA,
- .probe = mv88e6123_drv_probe,
- .setup = mv88e6xxx_setup,
- .set_addr = mv88e6xxx_set_addr,
- .phy_read = mv88e6xxx_phy_read,
- .phy_write = mv88e6xxx_phy_write,
- .set_eee = mv88e6xxx_set_eee,
- .get_eee = mv88e6xxx_get_eee,
- .get_strings = mv88e6xxx_get_strings,
- .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
- .get_sset_count = mv88e6xxx_get_sset_count,
- .adjust_link = mv88e6xxx_adjust_link,
-#ifdef CONFIG_NET_DSA_HWMON
- .get_temp = mv88e6xxx_get_temp,
- .get_temp_limit = mv88e6xxx_get_temp_limit,
- .set_temp_limit = mv88e6xxx_set_temp_limit,
- .get_temp_alarm = mv88e6xxx_get_temp_alarm,
-#endif
- .get_eeprom = mv88e6xxx_get_eeprom,
- .set_eeprom = mv88e6xxx_set_eeprom,
- .get_regs_len = mv88e6xxx_get_regs_len,
- .get_regs = mv88e6xxx_get_regs,
- .port_bridge_join = mv88e6xxx_port_bridge_join,
- .port_bridge_leave = mv88e6xxx_port_bridge_leave,
- .port_stp_state_set = mv88e6xxx_port_stp_state_set,
- .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
- .port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
- .port_vlan_add = mv88e6xxx_port_vlan_add,
- .port_vlan_del = mv88e6xxx_port_vlan_del,
- .port_vlan_dump = mv88e6xxx_port_vlan_dump,
- .port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
- .port_fdb_add = mv88e6xxx_port_fdb_add,
- .port_fdb_del = mv88e6xxx_port_fdb_del,
- .port_fdb_dump = mv88e6xxx_port_fdb_dump,
-};
-
-MODULE_ALIAS("platform:mv88e6123");
-MODULE_ALIAS("platform:mv88e6161");
-MODULE_ALIAS("platform:mv88e6165");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
deleted file mode 100644
index bbad199..0000000
--- a/drivers/net/dsa/mv88e6131.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * net/dsa/mv88e6131.c - Marvell 88e6095/6095f/6131 switch chip support
- * Copyright (c) 2008-2009 Marvell Semiconductor
- *
- * This program 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.
- */
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-#include <net/dsa.h>
-#include "mv88e6xxx.h"
-
-static const struct mv88e6xxx_info mv88e6131_table[] = {
- {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
- .family = MV88E6XXX_FAMILY_6095,
- .name = "Marvell 88E6095/88E6095F",
- .num_databases = 256,
- .num_ports = 11,
- .flags = MV88E6XXX_FLAGS_FAMILY_6095,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
- .family = MV88E6XXX_FAMILY_6097,
- .name = "Marvell 88E6085",
- .num_databases = 4096,
- .num_ports = 10,
- .flags = MV88E6XXX_FLAGS_FAMILY_6097,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
- .family = MV88E6XXX_FAMILY_6185,
- .name = "Marvell 88E6131",
- .num_databases = 256,
- .num_ports = 8,
- .flags = MV88E6XXX_FLAGS_FAMILY_6185,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
- .family = MV88E6XXX_FAMILY_6185,
- .name = "Marvell 88E6185",
- .num_databases = 256,
- .num_ports = 10,
- .flags = MV88E6XXX_FLAGS_FAMILY_6185,
- }
-};
-
-static const char *mv88e6131_drv_probe(struct device *dsa_dev,
- struct device *host_dev, int sw_addr,
- void **priv)
-{
- return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
- mv88e6131_table,
- ARRAY_SIZE(mv88e6131_table));
-}
-
-struct dsa_switch_driver mv88e6131_switch_driver = {
- .tag_protocol = DSA_TAG_PROTO_EDSA,
- .probe = mv88e6131_drv_probe,
- .setup = mv88e6xxx_setup,
- .set_addr = mv88e6xxx_set_addr,
- .phy_read = mv88e6xxx_phy_read,
- .phy_write = mv88e6xxx_phy_write,
- .set_eee = mv88e6xxx_set_eee,
- .get_eee = mv88e6xxx_get_eee,
- .get_strings = mv88e6xxx_get_strings,
- .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
- .get_sset_count = mv88e6xxx_get_sset_count,
- .get_eeprom = mv88e6xxx_get_eeprom,
- .set_eeprom = mv88e6xxx_set_eeprom,
- .get_regs_len = mv88e6xxx_get_regs_len,
- .get_regs = mv88e6xxx_get_regs,
-#ifdef CONFIG_NET_DSA_HWMON
- .get_temp = mv88e6xxx_get_temp,
- .get_temp_limit = mv88e6xxx_get_temp_limit,
- .set_temp_limit = mv88e6xxx_set_temp_limit,
- .get_temp_alarm = mv88e6xxx_get_temp_alarm,
-#endif
- .adjust_link = mv88e6xxx_adjust_link,
- .port_bridge_join = mv88e6xxx_port_bridge_join,
- .port_bridge_leave = mv88e6xxx_port_bridge_leave,
- .port_stp_state_set = mv88e6xxx_port_stp_state_set,
- .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
- .port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
- .port_vlan_add = mv88e6xxx_port_vlan_add,
- .port_vlan_del = mv88e6xxx_port_vlan_del,
- .port_vlan_dump = mv88e6xxx_port_vlan_dump,
- .port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
- .port_fdb_add = mv88e6xxx_port_fdb_add,
- .port_fdb_del = mv88e6xxx_port_fdb_del,
- .port_fdb_dump = mv88e6xxx_port_fdb_dump,
-};
-
-MODULE_ALIAS("platform:mv88e6085");
-MODULE_ALIAS("platform:mv88e6095");
-MODULE_ALIAS("platform:mv88e6095f");
-MODULE_ALIAS("platform:mv88e6131");
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
deleted file mode 100644
index 4bf517a..0000000
--- a/drivers/net/dsa/mv88e6171.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* net/dsa/mv88e6171.c - Marvell 88e6171 switch chip support
- * Copyright (c) 2008-2009 Marvell Semiconductor
- * Copyright (c) 2014 Claudio Leite <leitec@staticky.com>
- *
- * This program 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.
- */
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/phy.h>
-#include <net/dsa.h>
-#include "mv88e6xxx.h"
-
-static const struct mv88e6xxx_info mv88e6171_table[] = {
- {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
- .family = MV88E6XXX_FAMILY_6351,
- .name = "Marvell 88E6171",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6351,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
- .family = MV88E6XXX_FAMILY_6351,
- .name = "Marvell 88E6175",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6351,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
- .family = MV88E6XXX_FAMILY_6351,
- .name = "Marvell 88E6350",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6351,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
- .family = MV88E6XXX_FAMILY_6351,
- .name = "Marvell 88E6351",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6351,
- }
-};
-
-static const char *mv88e6171_drv_probe(struct device *dsa_dev,
- struct device *host_dev, int sw_addr,
- void **priv)
-{
- return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
- mv88e6171_table,
- ARRAY_SIZE(mv88e6171_table));
-}
-
-struct dsa_switch_driver mv88e6171_switch_driver = {
- .tag_protocol = DSA_TAG_PROTO_EDSA,
- .probe = mv88e6171_drv_probe,
- .setup = mv88e6xxx_setup,
- .set_addr = mv88e6xxx_set_addr,
- .phy_read = mv88e6xxx_phy_read,
- .phy_write = mv88e6xxx_phy_write,
- .set_eee = mv88e6xxx_set_eee,
- .get_eee = mv88e6xxx_get_eee,
- .get_strings = mv88e6xxx_get_strings,
- .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
- .get_sset_count = mv88e6xxx_get_sset_count,
- .adjust_link = mv88e6xxx_adjust_link,
-#ifdef CONFIG_NET_DSA_HWMON
- .get_temp = mv88e6xxx_get_temp,
- .get_temp_limit = mv88e6xxx_get_temp_limit,
- .set_temp_limit = mv88e6xxx_set_temp_limit,
- .get_temp_alarm = mv88e6xxx_get_temp_alarm,
-#endif
- .get_eeprom = mv88e6xxx_get_eeprom,
- .set_eeprom = mv88e6xxx_set_eeprom,
- .get_regs_len = mv88e6xxx_get_regs_len,
- .get_regs = mv88e6xxx_get_regs,
- .port_bridge_join = mv88e6xxx_port_bridge_join,
- .port_bridge_leave = mv88e6xxx_port_bridge_leave,
- .port_stp_state_set = mv88e6xxx_port_stp_state_set,
- .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
- .port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
- .port_vlan_add = mv88e6xxx_port_vlan_add,
- .port_vlan_del = mv88e6xxx_port_vlan_del,
- .port_vlan_dump = mv88e6xxx_port_vlan_dump,
- .port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
- .port_fdb_add = mv88e6xxx_port_fdb_add,
- .port_fdb_del = mv88e6xxx_port_fdb_del,
- .port_fdb_dump = mv88e6xxx_port_fdb_dump,
-};
-
-MODULE_ALIAS("platform:mv88e6171");
-MODULE_ALIAS("platform:mv88e6175");
-MODULE_ALIAS("platform:mv88e6350");
-MODULE_ALIAS("platform:mv88e6351");
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
deleted file mode 100644
index d65a90d..0000000
--- a/drivers/net/dsa/mv88e6352.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * net/dsa/mv88e6352.c - Marvell 88e6352 switch chip support
- *
- * Copyright (c) 2014 Guenter Roeck
- *
- * Derived from mv88e6123_61_65.c
- * Copyright (c) 2008-2009 Marvell Semiconductor
- *
- * This program 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.
- */
-
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/platform_device.h>
-#include <linux/phy.h>
-#include <net/dsa.h>
-#include "mv88e6xxx.h"
-
-static const struct mv88e6xxx_info mv88e6352_table[] = {
- {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
- .family = MV88E6XXX_FAMILY_6320,
- .name = "Marvell 88E6320",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6320,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
- .family = MV88E6XXX_FAMILY_6320,
- .name = "Marvell 88E6321",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6320,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
- .family = MV88E6XXX_FAMILY_6352,
- .name = "Marvell 88E6172",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6352,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
- .family = MV88E6XXX_FAMILY_6352,
- .name = "Marvell 88E6176",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6352,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
- .family = MV88E6XXX_FAMILY_6352,
- .name = "Marvell 88E6240",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6352,
- }, {
- .prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
- .family = MV88E6XXX_FAMILY_6352,
- .name = "Marvell 88E6352",
- .num_databases = 4096,
- .num_ports = 7,
- .flags = MV88E6XXX_FLAGS_FAMILY_6352,
- }
-};
-
-static const char *mv88e6352_drv_probe(struct device *dsa_dev,
- struct device *host_dev, int sw_addr,
- void **priv)
-{
- return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv,
- mv88e6352_table,
- ARRAY_SIZE(mv88e6352_table));
-}
-
-struct dsa_switch_driver mv88e6352_switch_driver = {
- .tag_protocol = DSA_TAG_PROTO_EDSA,
- .probe = mv88e6352_drv_probe,
- .setup = mv88e6xxx_setup,
- .set_addr = mv88e6xxx_set_addr,
- .phy_read = mv88e6xxx_phy_read,
- .phy_write = mv88e6xxx_phy_write,
- .get_strings = mv88e6xxx_get_strings,
- .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
- .get_sset_count = mv88e6xxx_get_sset_count,
- .adjust_link = mv88e6xxx_adjust_link,
- .set_eee = mv88e6xxx_set_eee,
- .get_eee = mv88e6xxx_get_eee,
-#ifdef CONFIG_NET_DSA_HWMON
- .get_temp = mv88e6xxx_get_temp,
- .get_temp_limit = mv88e6xxx_get_temp_limit,
- .set_temp_limit = mv88e6xxx_set_temp_limit,
- .get_temp_alarm = mv88e6xxx_get_temp_alarm,
-#endif
- .get_eeprom = mv88e6xxx_get_eeprom,
- .set_eeprom = mv88e6xxx_set_eeprom,
- .get_regs_len = mv88e6xxx_get_regs_len,
- .get_regs = mv88e6xxx_get_regs,
- .port_bridge_join = mv88e6xxx_port_bridge_join,
- .port_bridge_leave = mv88e6xxx_port_bridge_leave,
- .port_stp_state_set = mv88e6xxx_port_stp_state_set,
- .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
- .port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
- .port_vlan_add = mv88e6xxx_port_vlan_add,
- .port_vlan_del = mv88e6xxx_port_vlan_del,
- .port_vlan_dump = mv88e6xxx_port_vlan_dump,
- .port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
- .port_fdb_add = mv88e6xxx_port_fdb_add,
- .port_fdb_del = mv88e6xxx_port_fdb_del,
- .port_fdb_dump = mv88e6xxx_port_fdb_dump,
-};
-
-MODULE_ALIAS("platform:mv88e6172");
-MODULE_ALIAS("platform:mv88e6176");
-MODULE_ALIAS("platform:mv88e6320");
-MODULE_ALIAS("platform:mv88e6321");
-MODULE_ALIAS("platform:mv88e6352");
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 7ea3050..1e5ca8e 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -467,8 +467,8 @@ static bool mv88e6xxx_has_stu(struct mv88e6xxx_priv_state *ps)
* phy. However, in the case of a fixed link phy, we force the port
* settings from the fixed link settings.
*/
-void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
- struct phy_device *phydev)
+static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
+ struct phy_device *phydev)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
u32 reg;
@@ -714,7 +714,8 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_priv_state *ps,
return value;
}
-void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
+static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
+ uint8_t *data)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_hw_stat *stat;
@@ -730,7 +731,7 @@ void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
}
}
-int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
+static int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_hw_stat *stat;
@@ -744,9 +745,8 @@ int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
return j;
}
-void
-mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
- int port, uint64_t *data)
+static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
+ uint64_t *data)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_hw_stat *stat;
@@ -771,13 +771,13 @@ mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
mutex_unlock(&ps->smi_mutex);
}
-int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
+static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
{
return 32 * sizeof(u16);
}
-void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
- struct ethtool_regs *regs, void *_p)
+static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
+ struct ethtool_regs *regs, void *_p)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
u16 *p = _p;
@@ -876,8 +876,8 @@ error:
return ret;
}
-int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
- u8 *data)
+static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
+ struct ethtool_eeprom *eeprom, u8 *data)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int offset;
@@ -982,8 +982,8 @@ error:
return ret;
}
-int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
- u8 *data)
+static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
+ struct ethtool_eeprom *eeprom, u8 *data)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int offset;
@@ -1104,7 +1104,8 @@ static int _mv88e6xxx_phy_write_indirect(struct mv88e6xxx_priv_state *ps,
return _mv88e6xxx_phy_wait(ps);
}
-int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
+static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port,
+ struct ethtool_eee *e)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int reg;
@@ -1133,8 +1134,8 @@ out:
return reg;
}
-int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
- struct phy_device *phydev, struct ethtool_eee *e)
+static int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
+ struct phy_device *phydev, struct ethtool_eee *e)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int reg;
@@ -1364,7 +1365,8 @@ static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_priv_state *ps,
return _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_BASE_VLAN, reg);
}
-void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
+ u8 state)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int stp_state;
@@ -1587,9 +1589,9 @@ static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_priv_state *ps,
return 0;
}
-int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
- struct switchdev_obj_port_vlan *vlan,
- int (*cb)(struct switchdev_obj *obj))
+static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
+ struct switchdev_obj_port_vlan *vlan,
+ int (*cb)(struct switchdev_obj *obj))
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_vtu_stu_entry next;
@@ -2014,8 +2016,8 @@ static const char * const mv88e6xxx_port_8021q_mode_names[] = {
[PORT_CONTROL_2_8021Q_SECURE] = "Secure",
};
-int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
- bool vlan_filtering)
+static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
+ bool vlan_filtering)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
u16 old, new = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE :
@@ -2054,9 +2056,9 @@ unlock:
return ret;
}
-int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan,
- struct switchdev_trans *trans)
+static int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_vlan *vlan,
+ struct switchdev_trans *trans)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int err;
@@ -2095,9 +2097,9 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_priv_state *ps, int port,
return _mv88e6xxx_vtu_loadpurge(ps, &vlan);
}
-void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan,
- struct switchdev_trans *trans)
+static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_vlan *vlan,
+ struct switchdev_trans *trans)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
@@ -2157,8 +2159,8 @@ static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_priv_state *ps,
return _mv88e6xxx_atu_remove(ps, vlan.fid, port, false);
}
-int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan)
+static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_vlan *vlan)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
u16 pvid, vid;
@@ -2271,9 +2273,9 @@ static int _mv88e6xxx_port_fdb_load(struct mv88e6xxx_priv_state *ps, int port,
return _mv88e6xxx_atu_load(ps, &entry);
}
-int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_fdb *fdb,
- struct switchdev_trans *trans)
+static int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_fdb *fdb,
+ struct switchdev_trans *trans)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -2286,9 +2288,9 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
return 0;
}
-void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_fdb *fdb,
- struct switchdev_trans *trans)
+static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_fdb *fdb,
+ struct switchdev_trans *trans)
{
int state = is_multicast_ether_addr(fdb->addr) ?
GLOBAL_ATU_DATA_STATE_MC_STATIC :
@@ -2304,8 +2306,8 @@ void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
mutex_unlock(&ps->smi_mutex);
}
-int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_fdb *fdb)
+static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_fdb *fdb)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
@@ -2407,9 +2409,9 @@ static int _mv88e6xxx_port_fdb_dump_one(struct mv88e6xxx_priv_state *ps,
return err;
}
-int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
- struct switchdev_obj_port_fdb *fdb,
- int (*cb)(struct switchdev_obj *obj))
+static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
+ struct switchdev_obj_port_fdb *fdb,
+ int (*cb)(struct switchdev_obj *obj))
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_vtu_stu_entry vlan = {
@@ -2457,8 +2459,8 @@ unlock:
return err;
}
-int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
- struct net_device *bridge)
+static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
+ struct net_device *bridge)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int i, err = 0;
@@ -2484,7 +2486,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
return err;
}
-void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
+static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct net_device *bridge = ps->ports[port].bridge_dev;
@@ -3108,7 +3110,7 @@ static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps)
return err;
}
-int mv88e6xxx_setup(struct dsa_switch *ds)
+static int mv88e6xxx_setup(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int err;
@@ -3181,8 +3183,7 @@ static int mv88e6xxx_port_to_phy_addr(struct mv88e6xxx_priv_state *ps,
return -EINVAL;
}
-int
-mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
+static int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int addr = mv88e6xxx_port_to_phy_addr(ps, port);
@@ -3204,8 +3205,8 @@ mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum)
return ret;
}
-int
-mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
+static int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum,
+ u16 val)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int addr = mv88e6xxx_port_to_phy_addr(ps, port);
@@ -3291,7 +3292,7 @@ static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp)
return 0;
}
-int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
+static int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -3304,7 +3305,7 @@ int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
return mv88e61xx_get_temp(ds, temp);
}
-int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
+static int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
@@ -3324,7 +3325,7 @@ int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
return 0;
}
-int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
+static int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
@@ -3341,7 +3342,7 @@ int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
(ret & 0xe0ff) | (temp << 8));
}
-int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
+static int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int phy = mv88e6xxx_6320_family(ps) ? 3 : 0;
@@ -3362,6 +3363,161 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
}
#endif /* CONFIG_NET_DSA_HWMON */
+static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+ [MV88E6085] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
+ .family = MV88E6XXX_FAMILY_6097,
+ .name = "Marvell 88E6085",
+ .num_databases = 4096,
+ .num_ports = 10,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6097,
+ },
+
+ [MV88E6095] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
+ .family = MV88E6XXX_FAMILY_6095,
+ .name = "Marvell 88E6095/88E6095F",
+ .num_databases = 256,
+ .num_ports = 11,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6095,
+ },
+
+ [MV88E6123] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
+ .family = MV88E6XXX_FAMILY_6165,
+ .name = "Marvell 88E6123",
+ .num_databases = 4096,
+ .num_ports = 3,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6165,
+ },
+
+ [MV88E6131] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
+ .family = MV88E6XXX_FAMILY_6185,
+ .name = "Marvell 88E6131",
+ .num_databases = 256,
+ .num_ports = 8,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6185,
+ },
+
+ [MV88E6161] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
+ .family = MV88E6XXX_FAMILY_6165,
+ .name = "Marvell 88E6161",
+ .num_databases = 4096,
+ .num_ports = 6,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6165,
+ },
+
+ [MV88E6165] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
+ .family = MV88E6XXX_FAMILY_6165,
+ .name = "Marvell 88E6165",
+ .num_databases = 4096,
+ .num_ports = 6,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6165,
+ },
+
+ [MV88E6171] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
+ .family = MV88E6XXX_FAMILY_6351,
+ .name = "Marvell 88E6171",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6351,
+ },
+
+ [MV88E6172] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
+ .family = MV88E6XXX_FAMILY_6352,
+ .name = "Marvell 88E6172",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6352,
+ },
+
+ [MV88E6175] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
+ .family = MV88E6XXX_FAMILY_6351,
+ .name = "Marvell 88E6175",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6351,
+ },
+
+ [MV88E6176] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
+ .family = MV88E6XXX_FAMILY_6352,
+ .name = "Marvell 88E6176",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6352,
+ },
+
+ [MV88E6185] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
+ .family = MV88E6XXX_FAMILY_6185,
+ .name = "Marvell 88E6185",
+ .num_databases = 256,
+ .num_ports = 10,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6185,
+ },
+
+ [MV88E6240] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
+ .family = MV88E6XXX_FAMILY_6352,
+ .name = "Marvell 88E6240",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6352,
+ },
+
+ [MV88E6320] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
+ .family = MV88E6XXX_FAMILY_6320,
+ .name = "Marvell 88E6320",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6320,
+ },
+
+ [MV88E6321] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
+ .family = MV88E6XXX_FAMILY_6320,
+ .name = "Marvell 88E6321",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6320,
+ },
+
+ [MV88E6350] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
+ .family = MV88E6XXX_FAMILY_6351,
+ .name = "Marvell 88E6350",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6351,
+ },
+
+ [MV88E6351] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
+ .family = MV88E6XXX_FAMILY_6351,
+ .name = "Marvell 88E6351",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6351,
+ },
+
+ [MV88E6352] = {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
+ .family = MV88E6XXX_FAMILY_6352,
+ .name = "Marvell 88E6352",
+ .num_databases = 4096,
+ .num_ports = 7,
+ .flags = MV88E6XXX_FLAGS_FAMILY_6352,
+ },
+};
+
static const struct mv88e6xxx_info *
mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table,
unsigned int num)
@@ -3375,10 +3531,9 @@ mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table,
return NULL;
}
-const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
- int sw_addr, void **priv,
- const struct mv88e6xxx_info *table,
- unsigned int num)
+static const char *mv88e6xxx_probe(struct device *dsa_dev,
+ struct device *host_dev, int sw_addr,
+ void **priv)
{
const struct mv88e6xxx_info *info;
struct mv88e6xxx_priv_state *ps;
@@ -3397,7 +3552,8 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
prod_num = (id & 0xfff0) >> 4;
rev = id & 0x000f;
- info = mv88e6xxx_lookup_info(prod_num, table, num);
+ info = mv88e6xxx_lookup_info(prod_num, mv88e6xxx_table,
+ ARRAY_SIZE(mv88e6xxx_table));
if (!info)
return NULL;
@@ -3419,41 +3575,73 @@ const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
return name;
}
+struct dsa_switch_driver mv88e6xxx_switch_driver = {
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
+ .probe = mv88e6xxx_probe,
+ .setup = mv88e6xxx_setup,
+ .set_addr = mv88e6xxx_set_addr,
+ .phy_read = mv88e6xxx_phy_read,
+ .phy_write = mv88e6xxx_phy_write,
+ .adjust_link = mv88e6xxx_adjust_link,
+ .get_strings = mv88e6xxx_get_strings,
+ .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
+ .get_sset_count = mv88e6xxx_get_sset_count,
+ .set_eee = mv88e6xxx_set_eee,
+ .get_eee = mv88e6xxx_get_eee,
+#ifdef CONFIG_NET_DSA_HWMON
+ .get_temp = mv88e6xxx_get_temp,
+ .get_temp_limit = mv88e6xxx_get_temp_limit,
+ .set_temp_limit = mv88e6xxx_set_temp_limit,
+ .get_temp_alarm = mv88e6xxx_get_temp_alarm,
+#endif
+ .get_eeprom = mv88e6xxx_get_eeprom,
+ .set_eeprom = mv88e6xxx_set_eeprom,
+ .get_regs_len = mv88e6xxx_get_regs_len,
+ .get_regs = mv88e6xxx_get_regs,
+ .port_bridge_join = mv88e6xxx_port_bridge_join,
+ .port_bridge_leave = mv88e6xxx_port_bridge_leave,
+ .port_stp_state_set = mv88e6xxx_port_stp_state_set,
+ .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
+ .port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
+ .port_vlan_add = mv88e6xxx_port_vlan_add,
+ .port_vlan_del = mv88e6xxx_port_vlan_del,
+ .port_vlan_dump = mv88e6xxx_port_vlan_dump,
+ .port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
+ .port_fdb_add = mv88e6xxx_port_fdb_add,
+ .port_fdb_del = mv88e6xxx_port_fdb_del,
+ .port_fdb_dump = mv88e6xxx_port_fdb_dump,
+};
+
static int __init mv88e6xxx_init(void)
{
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
- register_switch_driver(&mv88e6131_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123)
- register_switch_driver(&mv88e6123_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
- register_switch_driver(&mv88e6352_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
- register_switch_driver(&mv88e6171_switch_driver);
-#endif
+ register_switch_driver(&mv88e6xxx_switch_driver);
+
return 0;
}
module_init(mv88e6xxx_init);
static void __exit mv88e6xxx_cleanup(void)
{
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
- unregister_switch_driver(&mv88e6171_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
- unregister_switch_driver(&mv88e6352_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123)
- unregister_switch_driver(&mv88e6123_switch_driver);
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
- unregister_switch_driver(&mv88e6131_switch_driver);
-#endif
+ unregister_switch_driver(&mv88e6xxx_switch_driver);
}
module_exit(mv88e6xxx_cleanup);
+MODULE_ALIAS("platform:mv88e6085");
+MODULE_ALIAS("platform:mv88e6095");
+MODULE_ALIAS("platform:mv88e6095f");
+MODULE_ALIAS("platform:mv88e6123");
+MODULE_ALIAS("platform:mv88e6131");
+MODULE_ALIAS("platform:mv88e6161");
+MODULE_ALIAS("platform:mv88e6165");
+MODULE_ALIAS("platform:mv88e6171");
+MODULE_ALIAS("platform:mv88e6172");
+MODULE_ALIAS("platform:mv88e6175");
+MODULE_ALIAS("platform:mv88e6176");
+MODULE_ALIAS("platform:mv88e6320");
+MODULE_ALIAS("platform:mv88e6321");
+MODULE_ALIAS("platform:mv88e6350");
+MODULE_ALIAS("platform:mv88e6351");
+MODULE_ALIAS("platform:mv88e6352");
MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index a131827..ca69a93 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -338,6 +338,27 @@
#define MV88E6XXX_N_FID 4096
+/* List of supported models */
+enum mv88e6xxx_model {
+ MV88E6085,
+ MV88E6095,
+ MV88E6123,
+ MV88E6131,
+ MV88E6161,
+ MV88E6165,
+ MV88E6171,
+ MV88E6172,
+ MV88E6175,
+ MV88E6176,
+ MV88E6185,
+ MV88E6240,
+ MV88E6320,
+ MV88E6321,
+ MV88E6350,
+ MV88E6351,
+ MV88E6352,
+};
+
enum mv88e6xxx_family {
MV88E6XXX_FAMILY_NONE,
MV88E6XXX_FAMILY_6065, /* 6031 6035 6061 6065 */
@@ -583,74 +604,4 @@ static inline bool mv88e6xxx_has(struct mv88e6xxx_priv_state *ps,
return (ps->info->flags & flags) == flags;
}
-const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
- int sw_addr, void **priv,
- const struct mv88e6xxx_info *table,
- unsigned int num);
-
-int mv88e6xxx_setup(struct dsa_switch *ds);
-int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg);
-int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr,
- int reg, u16 val);
-int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr);
-int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum);
-int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val);
-void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data);
-void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
- uint64_t *data);
-int mv88e6xxx_get_sset_count(struct dsa_switch *ds);
-int mv88e6xxx_get_sset_count_basic(struct dsa_switch *ds);
-void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
- struct phy_device *phydev);
-int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port);
-void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
- struct ethtool_regs *regs, void *_p);
-int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp);
-int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp);
-int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp);
-int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm);
-int mv88e6xxx_get_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
- u8 *data);
-int mv88e6xxx_set_eeprom(struct dsa_switch *ds, struct ethtool_eeprom *eeprom,
- u8 *data);
-int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
-int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
- struct phy_device *phydev, struct ethtool_eee *e);
-int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
- struct net_device *bridge);
-void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port);
-void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
-int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
- bool vlan_filtering);
-int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan,
- struct switchdev_trans *trans);
-void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan,
- struct switchdev_trans *trans);
-int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_vlan *vlan);
-int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
- struct switchdev_obj_port_vlan *vlan,
- int (*cb)(struct switchdev_obj *obj));
-int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_fdb *fdb,
- struct switchdev_trans *trans);
-void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_fdb *fdb,
- struct switchdev_trans *trans);
-int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_fdb *fdb);
-int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
- struct switchdev_obj_port_fdb *fdb,
- int (*cb)(struct switchdev_obj *obj));
-int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg);
-int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page,
- int reg, int val);
-
-extern struct dsa_switch_driver mv88e6131_switch_driver;
-extern struct dsa_switch_driver mv88e6123_switch_driver;
-extern struct dsa_switch_driver mv88e6352_switch_driver;
-extern struct dsa_switch_driver mv88e6171_switch_driver;
-
#endif
--
2.8.2
^ permalink raw reply related
* [PATCH net-next v2 18/21] net: dsa: mv88e6131: drop frames priorities setup
From: Vivien Didelot @ 2016-05-09 17:22 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1462814578-6249-1-git-send-email-vivien.didelot@savoirfairelinux.com>
6131 is the only driver which setups the priority of IGMP/MLD snoop
frames and ARP frames to the highest setting. Drop such change until we
figure out a common configuration for all switch models.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6131.c | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index b6ca07b..da28327 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -58,20 +58,6 @@ static const char *mv88e6131_drv_probe(struct device *dsa_dev,
ARRAY_SIZE(mv88e6131_table));
}
-static int mv88e6131_setup_global(struct dsa_switch *ds)
-{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-
- /* Force the priority of IGMP/MLD snoop frames and ARP frames
- * to the highest setting.
- */
- return mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE,
- GLOBAL2_PRIO_OVERRIDE_FORCE_SNOOP |
- 7 << GLOBAL2_PRIO_OVERRIDE_SNOOP_SHIFT |
- GLOBAL2_PRIO_OVERRIDE_FORCE_ARP |
- 7 << GLOBAL2_PRIO_OVERRIDE_ARP_SHIFT);
-}
-
static int mv88e6131_setup(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -83,10 +69,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
if (ret < 0)
return ret;
- ret = mv88e6131_setup_global(ds);
- if (ret < 0)
- return ret;
-
return mv88e6xxx_setup_ports(ds);
}
--
2.8.2
^ permalink raw reply related
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