* [PATCH 3/7][RFC] netfilter: qtaguid: initialize a local var to keep compiler happy.
From: John Stultz @ 2012-09-22 2:10 UTC (permalink / raw)
To: LKML; +Cc: JP Abgrall, netdev, Ashish Sharma, Peter P Waskiewicz Jr,
John Stultz
In-Reply-To: <1348279853-44499-1-git-send-email-john.stultz@linaro.org>
From: JP Abgrall <jpa@google.com>
There was a case that might have seemed like new_tag_stat was not
initialized and actually used.
Added comment explaining why it was impossible, and a BUG()
in case the logic gets changed.
Cc: netdev@vger.kernel.org
Cc: JP Abgrall <jpa@google.com>
Cc: Ashish Sharma <ashishsharma@google.com>
Cc: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: JP Abgrall <jpa@google.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
net/netfilter/xt_qtaguid.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 7c4ac46..214a990 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -1255,7 +1255,7 @@ static void if_tag_stat_update(const char *ifname, uid_t uid,
struct data_counters *uid_tag_counters;
struct sock_tag *sock_tag_entry;
struct iface_stat *iface_entry;
- struct tag_stat *new_tag_stat;
+ struct tag_stat *new_tag_stat = NULL;
MT_DEBUG("qtaguid: if_tag_stat_update(ifname=%s "
"uid=%u sk=%p dir=%d proto=%d bytes=%d)\n",
ifname, uid, sk, direction, proto, bytes);
@@ -1320,8 +1320,19 @@ static void if_tag_stat_update(const char *ifname, uid_t uid,
}
if (acct_tag) {
+ /* Create the child {acct_tag, uid_tag} and hook up parent. */
new_tag_stat = create_if_tag_stat(iface_entry, tag);
new_tag_stat->parent_counters = uid_tag_counters;
+ } else {
+ /*
+ * For new_tag_stat to be still NULL here would require:
+ * {0, uid_tag} exists
+ * and {acct_tag, uid_tag} doesn't exist
+ * AND acct_tag == 0.
+ * Impossible. This reassures us that new_tag_stat
+ * below will always be assigned.
+ */
+ BUG_ON(!new_tag_stat);
}
tag_stat_update(new_tag_stat, direction, proto, bytes);
spin_unlock_bh(&iface_entry->tag_stat_list_lock);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 4/7][RFC] netfilter: xt_qtaguid: fix ipv6 protocol lookup
From: John Stultz @ 2012-09-22 2:10 UTC (permalink / raw)
To: LKML; +Cc: JP Abgrall, netdev, Ashish Sharma, Peter P Waskiewicz Jr,
John Stultz
In-Reply-To: <1348279853-44499-1-git-send-email-john.stultz@linaro.org>
From: JP Abgrall <jpa@google.com>
When updating the stats for a given uid it would incorrectly assume
IPV4 and pick up the wrong protocol when IPV6.
Cc: netdev@vger.kernel.org
Cc: JP Abgrall <jpa@google.com>
Cc: Ashish Sharma <ashishsharma@google.com>
Cc: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: JP Abgrall <jpa@google.com>
[Small compile fix for ipv6_find_hdr() -jstultz]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
net/netfilter/xt_qtaguid.c | 39 ++++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 214a990..47dfb9e 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -26,6 +26,10 @@
#include <net/tcp.h>
#include <net/udp.h>
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#endif
+
#include <linux/netfilter/xt_socket.h>
#include "xt_qtaguid_internal.h"
#include "xt_qtaguid_print.h"
@@ -1536,6 +1540,27 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
return sk;
}
+static int ipx_proto(const struct sk_buff *skb,
+ struct xt_action_param *par)
+{
+ int thoff, tproto;
+
+ switch (par->family) {
+ case NFPROTO_IPV6:
+ tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
+ if (tproto < 0)
+ MT_DEBUG("%s(): transport header not found in ipv6"
+ " skb=%p\n", __func__, skb);
+ break;
+ case NFPROTO_IPV4:
+ tproto = ip_hdr(skb)->protocol;
+ break;
+ default:
+ tproto = IPPROTO_RAW;
+ }
+ return tproto;
+}
+
static void account_for_uid(const struct sk_buff *skb,
const struct sock *alternate_sk, uid_t uid,
struct xt_action_param *par)
@@ -1562,15 +1587,15 @@ static void account_for_uid(const struct sk_buff *skb,
} else if (unlikely(!el_dev->name)) {
pr_info("qtaguid[%d]: no dev->name?!!\n", par->hooknum);
} else {
- MT_DEBUG("qtaguid[%d]: dev name=%s type=%d\n",
- par->hooknum,
- el_dev->name,
- el_dev->type);
+ int proto = ipx_proto(skb, par);
+ MT_DEBUG("qtaguid[%d]: dev name=%s type=%d fam=%d proto=%d\n",
+ par->hooknum, el_dev->name, el_dev->type,
+ par->family, proto);
if_tag_stat_update(el_dev->name, uid,
skb->sk ? skb->sk : alternate_sk,
par->in ? IFS_RX : IFS_TX,
- ip_hdr(skb)->protocol, skb->len);
+ proto, skb->len);
}
}
@@ -1615,8 +1640,8 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
} else {
atomic64_inc(&qtu_events.match_found_sk);
}
- MT_DEBUG("qtaguid[%d]: sk=%p got_sock=%d proto=%d\n",
- par->hooknum, sk, got_sock, ip_hdr(skb)->protocol);
+ MT_DEBUG("qtaguid[%d]: sk=%p got_sock=%d fam=%d proto=%d\n",
+ par->hooknum, sk, got_sock, par->family, ipx_proto(skb, par));
if (sk != NULL) {
MT_DEBUG("qtaguid[%d]: sk=%p->sk_socket=%p->file=%p\n",
par->hooknum, sk, sk->sk_socket,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 5/7][RFC] netfilter: xt_qtaguid: start tracking iface rx/tx at low level
From: John Stultz @ 2012-09-22 2:10 UTC (permalink / raw)
To: LKML; +Cc: JP Abgrall, netdev, Ashish Sharma, Peter P Waskiewicz Jr,
John Stultz
In-Reply-To: <1348279853-44499-1-git-send-email-john.stultz@linaro.org>
From: JP Abgrall <jpa@google.com>
qtaguid tracks the device stats by monitoring when it goes up and down,
then it gets the dev_stats().
But devs don't correctly report stats (either they don't count headers
symmetrically between rx/tx, or they count internal control messages).
Now qtaguid counts the rx/tx bytes/packets during raw:prerouting and
mangle:postrouting (nat is not available in ipv6).
The results are in
/proc/net/xt_qtaguid/iface_stat_fmt
which outputs a format line (bash expansion):
ifname total_skb_{rx,tx}_{bytes,packets}
Added event counters for pre/post handling.
Added extra ctrl_*() pid/uid debugging.
Cc: netdev@vger.kernel.org
Cc: JP Abgrall <jpa@google.com>
Cc: Ashish Sharma <ashishsharma@google.com>
Cc: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: JP Abgrall <jpa@google.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
net/netfilter/xt_qtaguid.c | 277 +++++++++++++++++++++++++++--------
net/netfilter/xt_qtaguid_internal.h | 5 +-
net/netfilter/xt_qtaguid_print.c | 18 ++-
3 files changed, 233 insertions(+), 67 deletions(-)
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 47dfb9e..f490ef5 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -104,8 +104,15 @@ module_param_named(debug_mask, qtaguid_debug_mask, uint, S_IRUGO | S_IWUSR);
/*---------------------------------------------------------------------------*/
static const char *iface_stat_procdirname = "iface_stat";
static struct proc_dir_entry *iface_stat_procdir;
+/*
+ * The iface_stat_all* will go away once userspace gets use to the new fields
+ * that have a format line.
+ */
static const char *iface_stat_all_procfilename = "iface_stat_all";
static struct proc_dir_entry *iface_stat_all_procfile;
+static const char *iface_stat_fmt_procfilename = "iface_stat_fmt";
+static struct proc_dir_entry *iface_stat_fmt_procfile;
+
/*
* Ordering of locks:
@@ -118,9 +125,9 @@ static struct proc_dir_entry *iface_stat_all_procfile;
* Notice how sock_tag_list_lock is held sometimes when uid_tag_data_tree_lock
* is acquired.
*
- * Call tree with all lock holders as of 2011-09-25:
+ * Call tree with all lock holders as of 2012-04-27:
*
- * iface_stat_all_proc_read()
+ * iface_stat_fmt_proc_read()
* iface_stat_list_lock
* (struct iface_stat)
*
@@ -771,13 +778,14 @@ done:
return iface_entry;
}
-static int iface_stat_all_proc_read(char *page, char **num_items_returned,
+static int iface_stat_fmt_proc_read(char *page, char **num_items_returned,
off_t items_to_skip, int char_count,
int *eof, void *data)
{
char *outp = page;
int item_index = 0;
int len;
+ int fmt = (int)data; /* The data is just 1 (old) or 2 (uses fmt) */
struct iface_stat *iface_entry;
struct rtnl_link_stats64 dev_stats, *stats;
struct rtnl_link_stats64 no_dev_stats = {0};
@@ -787,14 +795,32 @@ static int iface_stat_all_proc_read(char *page, char **num_items_returned,
return 0;
}
- CT_DEBUG("qtaguid:proc iface_stat_all "
+ CT_DEBUG("qtaguid:proc iface_stat_fmt "
+ "pid=%u tgid=%u uid=%u "
"page=%p *num_items_returned=%p off=%ld "
- "char_count=%d *eof=%d\n", page, *num_items_returned,
+ "char_count=%d *eof=%d\n",
+ current->pid, current->tgid, current_fsuid(),
+ page, *num_items_returned,
items_to_skip, char_count, *eof);
if (*eof)
return 0;
+ if (fmt == 2 && item_index++ >= items_to_skip) {
+ len = snprintf(outp, char_count,
+ "ifname "
+ "total_skb_rx_bytes total_skb_rx_packets "
+ "total_skb_tx_bytes total_skb_tx_packets\n"
+ );
+ if (len >= char_count) {
+ *outp = '\0';
+ return outp - page;
+ }
+ outp += len;
+ char_count -= len;
+ (*num_items_returned)++;
+ }
+
/*
* This lock will prevent iface_stat_update() from changing active,
* and in turn prevent an interface from unregistering itself.
@@ -810,18 +836,37 @@ static int iface_stat_all_proc_read(char *page, char **num_items_returned,
} else {
stats = &no_dev_stats;
}
- len = snprintf(outp, char_count,
- "%s %d "
- "%llu %llu %llu %llu "
- "%llu %llu %llu %llu\n",
- iface_entry->ifname,
- iface_entry->active,
- iface_entry->totals[IFS_RX].bytes,
- iface_entry->totals[IFS_RX].packets,
- iface_entry->totals[IFS_TX].bytes,
- iface_entry->totals[IFS_TX].packets,
- stats->rx_bytes, stats->rx_packets,
- stats->tx_bytes, stats->tx_packets);
+ /*
+ * If the meaning of the data changes, then update the fmtX
+ * string.
+ */
+ if (fmt == 1) {
+ len = snprintf(
+ outp, char_count,
+ "%s %d "
+ "%llu %llu %llu %llu "
+ "%llu %llu %llu %llu\n",
+ iface_entry->ifname,
+ iface_entry->active,
+ iface_entry->totals_via_dev[IFS_RX].bytes,
+ iface_entry->totals_via_dev[IFS_RX].packets,
+ iface_entry->totals_via_dev[IFS_TX].bytes,
+ iface_entry->totals_via_dev[IFS_TX].packets,
+ stats->rx_bytes, stats->rx_packets,
+ stats->tx_bytes, stats->tx_packets
+ );
+ } else {
+ len = snprintf(
+ outp, char_count,
+ "%s "
+ "%llu %llu %llu %llu\n",
+ iface_entry->ifname,
+ iface_entry->totals_via_skb[IFS_RX].bytes,
+ iface_entry->totals_via_skb[IFS_RX].packets,
+ iface_entry->totals_via_skb[IFS_TX].bytes,
+ iface_entry->totals_via_skb[IFS_TX].packets
+ );
+ }
if (len >= char_count) {
spin_unlock_bh(&iface_stat_list_lock);
*outp = '\0';
@@ -855,13 +900,17 @@ static void iface_create_proc_worker(struct work_struct *work)
new_iface->proc_ptr = proc_entry;
create_proc_read_entry("tx_bytes", proc_iface_perms, proc_entry,
- read_proc_u64, &new_iface->totals[IFS_TX].bytes);
+ read_proc_u64,
+ &new_iface->totals_via_dev[IFS_TX].bytes);
create_proc_read_entry("rx_bytes", proc_iface_perms, proc_entry,
- read_proc_u64, &new_iface->totals[IFS_RX].bytes);
+ read_proc_u64,
+ &new_iface->totals_via_dev[IFS_RX].bytes);
create_proc_read_entry("tx_packets", proc_iface_perms, proc_entry,
- read_proc_u64, &new_iface->totals[IFS_TX].packets);
+ read_proc_u64,
+ &new_iface->totals_via_dev[IFS_TX].packets);
create_proc_read_entry("rx_packets", proc_iface_perms, proc_entry,
- read_proc_u64, &new_iface->totals[IFS_RX].packets);
+ read_proc_u64,
+ &new_iface->totals_via_dev[IFS_RX].packets);
create_proc_read_entry("active", proc_iface_perms, proc_entry,
read_proc_bool, &new_iface->active);
@@ -965,11 +1014,13 @@ static void iface_check_stats_reset_and_adjust(struct net_device *net_dev,
"iface reset its stats unexpectedly\n", __func__,
net_dev->name);
- iface->totals[IFS_TX].bytes += iface->last_known[IFS_TX].bytes;
- iface->totals[IFS_TX].packets +=
+ iface->totals_via_dev[IFS_TX].bytes +=
+ iface->last_known[IFS_TX].bytes;
+ iface->totals_via_dev[IFS_TX].packets +=
iface->last_known[IFS_TX].packets;
- iface->totals[IFS_RX].bytes += iface->last_known[IFS_RX].bytes;
- iface->totals[IFS_RX].packets +=
+ iface->totals_via_dev[IFS_RX].bytes +=
+ iface->last_known[IFS_RX].bytes;
+ iface->totals_via_dev[IFS_RX].packets +=
iface->last_known[IFS_RX].packets;
iface->last_known_valid = false;
IF_DEBUG("qtaguid: %s(%s): iface=%p "
@@ -1137,6 +1188,27 @@ static struct sock_tag *get_sock_stat(const struct sock *sk)
return sock_tag_entry;
}
+static int ipx_proto(const struct sk_buff *skb,
+ struct xt_action_param *par)
+{
+ int thoff, tproto;
+
+ switch (par->family) {
+ case NFPROTO_IPV6:
+ tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
+ if (tproto < 0)
+ MT_DEBUG("%s(): transport header not found in ipv6"
+ " skb=%p\n", __func__, skb);
+ break;
+ case NFPROTO_IPV4:
+ tproto = ip_hdr(skb)->protocol;
+ break;
+ default:
+ tproto = IPPROTO_RAW;
+ }
+ return tproto;
+}
+
static void
data_counters_update(struct data_counters *dc, int set,
enum ifs_tx_rx direction, int proto, int bytes)
@@ -1197,10 +1269,10 @@ static void iface_stat_update(struct net_device *net_dev, bool stash_only)
spin_unlock_bh(&iface_stat_list_lock);
return;
}
- entry->totals[IFS_TX].bytes += stats->tx_bytes;
- entry->totals[IFS_TX].packets += stats->tx_packets;
- entry->totals[IFS_RX].bytes += stats->rx_bytes;
- entry->totals[IFS_RX].packets += stats->rx_packets;
+ entry->totals_via_dev[IFS_TX].bytes += stats->tx_bytes;
+ entry->totals_via_dev[IFS_TX].packets += stats->tx_packets;
+ entry->totals_via_dev[IFS_RX].bytes += stats->rx_bytes;
+ entry->totals_via_dev[IFS_RX].packets += stats->rx_packets;
/* We don't need the last_known[] anymore */
entry->last_known_valid = false;
_iface_stat_set_active(entry, net_dev, false);
@@ -1210,6 +1282,67 @@ static void iface_stat_update(struct net_device *net_dev, bool stash_only)
spin_unlock_bh(&iface_stat_list_lock);
}
+/*
+ * Update stats for the specified interface from the skb.
+ * Do nothing if the entry
+ * does not exist (when a device was never configured with an IP address).
+ * Called on each sk.
+ */
+static void iface_stat_update_from_skb(const struct sk_buff *skb,
+ struct xt_action_param *par)
+{
+ struct iface_stat *entry;
+ const struct net_device *el_dev;
+ enum ifs_tx_rx direction = par->in ? IFS_RX : IFS_TX;
+ int bytes = skb->len;
+
+ if (!skb->dev) {
+ MT_DEBUG("qtaguid[%d]: no skb->dev\n", par->hooknum);
+ el_dev = par->in ? : par->out;
+ } else {
+ const struct net_device *other_dev;
+ el_dev = skb->dev;
+ other_dev = par->in ? : par->out;
+ if (el_dev != other_dev) {
+ MT_DEBUG("qtaguid[%d]: skb->dev=%p %s vs "
+ "par->(in/out)=%p %s\n",
+ par->hooknum, el_dev, el_dev->name, other_dev,
+ other_dev->name);
+ }
+ }
+
+ if (unlikely(!el_dev)) {
+ pr_err("qtaguid[%d]: %s(): no par->in/out?!!\n",
+ par->hooknum, __func__);
+ BUG();
+ } else if (unlikely(!el_dev->name)) {
+ pr_err("qtaguid[%d]: %s(): no dev->name?!!\n",
+ par->hooknum, __func__);
+ BUG();
+ } else {
+ int proto = ipx_proto(skb, par);
+ MT_DEBUG("qtaguid[%d]: dev name=%s type=%d fam=%d proto=%d\n",
+ par->hooknum, el_dev->name, el_dev->type,
+ par->family, proto);
+ }
+
+ spin_lock_bh(&iface_stat_list_lock);
+ entry = get_iface_entry(el_dev->name);
+ if (entry == NULL) {
+ IF_DEBUG("qtaguid: iface_stat: %s(%s): not tracked\n",
+ __func__, el_dev->name);
+ spin_unlock_bh(&iface_stat_list_lock);
+ return;
+ }
+
+ IF_DEBUG("qtaguid: %s(%s): entry=%p\n", __func__,
+ el_dev->name, entry);
+
+ entry->totals_via_skb[direction].bytes += bytes;
+ entry->totals_via_skb[direction].packets++;
+ spin_unlock_bh(&iface_stat_list_lock);
+}
+
static void tag_stat_update(struct tag_stat *tag_entry,
enum ifs_tx_rx direction, int proto, int bytes)
{
@@ -1457,18 +1590,31 @@ static int __init iface_stat_init(struct proc_dir_entry *parent_procdir)
parent_procdir);
if (!iface_stat_all_procfile) {
pr_err("qtaguid: iface_stat: init "
- " failed to create stat_all proc entry\n");
+ " failed to create stat_old proc entry\n");
err = -1;
goto err_zap_entry;
}
- iface_stat_all_procfile->read_proc = iface_stat_all_proc_read;
+ iface_stat_all_procfile->read_proc = iface_stat_fmt_proc_read;
+ iface_stat_all_procfile->data = (void *)1; /* fmt1 */
+
+ iface_stat_fmt_procfile = create_proc_entry(iface_stat_fmt_procfilename,
+ proc_iface_perms,
+ parent_procdir);
+ if (!iface_stat_fmt_procfile) {
+ pr_err("qtaguid: iface_stat: init "
+ " failed to create stat_all proc entry\n");
+ err = -1;
+ goto err_zap_all_stats_entry;
+ }
+ iface_stat_fmt_procfile->read_proc = iface_stat_fmt_proc_read;
+ iface_stat_fmt_procfile->data = (void *)2; /* fmt2 */
err = register_netdevice_notifier(&iface_netdev_notifier_blk);
if (err) {
pr_err("qtaguid: iface_stat: init "
"failed to register dev event handler\n");
- goto err_zap_all_stats_entry;
+ goto err_zap_all_stats_entries;
}
err = register_inetaddr_notifier(&iface_inetaddr_notifier_blk);
if (err) {
@@ -1489,6 +1635,8 @@ err_unreg_ip4_addr:
unregister_inetaddr_notifier(&iface_inetaddr_notifier_blk);
err_unreg_nd:
unregister_netdevice_notifier(&iface_netdev_notifier_blk);
+err_zap_all_stats_entries:
+ remove_proc_entry(iface_stat_fmt_procfilename, parent_procdir);
err_zap_all_stats_entry:
remove_proc_entry(iface_stat_all_procfilename, parent_procdir);
err_zap_entry:
@@ -1540,27 +1688,6 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
return sk;
}
-static int ipx_proto(const struct sk_buff *skb,
- struct xt_action_param *par)
-{
- int thoff, tproto;
-
- switch (par->family) {
- case NFPROTO_IPV6:
- tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
- if (tproto < 0)
- MT_DEBUG("%s(): transport header not found in ipv6"
- " skb=%p\n", __func__, skb);
- break;
- case NFPROTO_IPV4:
- tproto = ip_hdr(skb)->protocol;
- break;
- default:
- tproto = IPPROTO_RAW;
- }
- return tproto;
-}
-
static void account_for_uid(const struct sk_buff *skb,
const struct sock *alternate_sk, uid_t uid,
struct xt_action_param *par)
@@ -1620,8 +1747,22 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
goto ret_res;
}
- sk = skb->sk;
+ switch (par->hooknum) {
+ case NF_INET_PRE_ROUTING:
+ case NF_INET_POST_ROUTING:
+ atomic64_inc(&qtu_events.match_calls_prepost);
+ iface_stat_update_from_skb(skb, par);
+ /*
+ * We are done in pre/post. The skb will get processed
+ * further alter.
+ */
+ res = (info->match ^ info->invert);
+ goto ret_res;
+ break;
+ /* default: Fall through and do UID releated work */
+ }
+ sk = skb->sk;
if (sk == NULL) {
/*
* A missing sk->sk_socket happens when packets are in-flight
@@ -1796,8 +1937,10 @@ static int qtaguid_ctrl_proc_read(char *page, char **num_items_returned,
if (*eof)
return 0;
- CT_DEBUG("qtaguid: proc ctrl page=%p off=%ld char_count=%d *eof=%d\n",
- page, items_to_skip, char_count, *eof);
+ CT_DEBUG("qtaguid: proc ctrl pid=%u tgid=%u uid=%u "
+ "page=%p off=%ld char_count=%d *eof=%d\n",
+ current->pid, current->tgid, current_fsuid(),
+ page, items_to_skip, char_count, *eof);
spin_lock_bh(&sock_tag_list_lock);
for (node = rb_first(&sock_tag_tree);
@@ -1841,6 +1984,7 @@ static int qtaguid_ctrl_proc_read(char *page, char **num_items_returned,
"delete_cmds=%llu "
"iface_events=%llu "
"match_calls=%llu "
+ "match_calls_prepost=%llu "
"match_found_sk=%llu "
"match_found_sk_in_ct=%llu "
"match_found_no_sk_in_ct=%llu "
@@ -1852,6 +1996,7 @@ static int qtaguid_ctrl_proc_read(char *page, char **num_items_returned,
atomic64_read(&qtu_events.delete_cmds),
atomic64_read(&qtu_events.iface_events),
atomic64_read(&qtu_events.match_calls),
+ atomic64_read(&qtu_events.match_calls_prepost),
atomic64_read(&qtu_events.match_found_sk),
atomic64_read(&qtu_events.match_found_sk_in_ct),
atomic64_read(
@@ -2125,7 +2270,9 @@ static int ctrl_cmd_tag(const char *input)
el_socket = sockfd_lookup(sock_fd, &res); /* This locks the file */
if (!el_socket) {
pr_info("qtaguid: ctrl_tag(%s): failed to lookup"
- " sock_fd=%d err=%d\n", input, sock_fd, res);
+ " sock_fd=%d err=%d pid=%u tgid=%u uid=%u\n",
+ input, sock_fd, res, current->pid, current->tgid,
+ current_fsuid());
goto err;
}
CT_DEBUG("qtaguid: ctrl_tag(%s): socket->...->f_count=%ld ->sk=%p\n",
@@ -2270,7 +2417,9 @@ static int ctrl_cmd_untag(const char *input)
el_socket = sockfd_lookup(sock_fd, &res); /* This locks the file */
if (!el_socket) {
pr_info("qtaguid: ctrl_untag(%s): failed to lookup"
- " sock_fd=%d err=%d\n", input, sock_fd, res);
+ " sock_fd=%d err=%d pid=%u tgid=%u uid=%u\n",
+ input, sock_fd, res, current->pid, current->tgid,
+ current_fsuid());
goto err;
}
CT_DEBUG("qtaguid: ctrl_untag(%s): socket->...->f_count=%ld ->sk=%p\n",
@@ -2346,6 +2495,9 @@ static int qtaguid_ctrl_parse(const char *input, int count)
char cmd;
int res;
+ CT_DEBUG("qtaguid: ctrl(%s): pid=%u tgid=%u uid=%u\n",
+ input, current->pid, current->tgid, current_fsuid());
+
cmd = input[0];
/* Collect params for commands */
switch (cmd) {
@@ -2522,9 +2674,12 @@ static int qtaguid_stats_proc_read(char *page, char **num_items_returned,
return len;
}
- CT_DEBUG("qtaguid:proc stats page=%p *num_items_returned=%p off=%ld "
- "char_count=%d *eof=%d\n", page, *num_items_returned,
- items_to_skip, char_count, *eof);
+ CT_DEBUG("qtaguid:proc stats pid=%u tgid=%u uid=%u "
+ "page=%p *num_items_returned=%p off=%ld "
+ "char_count=%d *eof=%d\n",
+ current->pid, current->tgid, current_fsuid(),
+ page, *num_items_returned,
+ items_to_skip, char_count, *eof);
if (*eof)
return 0;
diff --git a/net/netfilter/xt_qtaguid_internal.h b/net/netfilter/xt_qtaguid_internal.h
index 02479d6..d79f838 100644
--- a/net/netfilter/xt_qtaguid_internal.h
+++ b/net/netfilter/xt_qtaguid_internal.h
@@ -202,7 +202,8 @@ struct iface_stat {
/* net_dev is only valid for active iface_stat */
struct net_device *net_dev;
- struct byte_packet_counters totals[IFS_MAX_DIRECTIONS];
+ struct byte_packet_counters totals_via_dev[IFS_MAX_DIRECTIONS];
+ struct byte_packet_counters totals_via_skb[IFS_MAX_DIRECTIONS];
/*
* We keep the last_known, because some devices reset their counters
* just before NETDEV_UP, while some will reset just before
@@ -254,6 +255,8 @@ struct qtaguid_event_counts {
atomic64_t iface_events; /* Number of NETDEV_* events handled */
atomic64_t match_calls; /* Number of times iptables called mt */
+ /* Number of times iptables called mt from pre or post routing hooks */
+ atomic64_t match_calls_prepost;
/*
* match_found_sk_*: numbers related to the netfilter matching
* function finding a sock for the sk_buff.
diff --git a/net/netfilter/xt_qtaguid_print.c b/net/netfilter/xt_qtaguid_print.c
index 3917678..8cbd8e4 100644
--- a/net/netfilter/xt_qtaguid_print.c
+++ b/net/netfilter/xt_qtaguid_print.c
@@ -183,7 +183,11 @@ char *pp_iface_stat(struct iface_stat *is)
res = kasprintf(GFP_ATOMIC, "iface_stat@%p{"
"list=list_head{...}, "
"ifname=%s, "
- "total={rx={bytes=%llu, "
+ "total_dev={rx={bytes=%llu, "
+ "packets=%llu}, "
+ "tx={bytes=%llu, "
+ "packets=%llu}}, "
+ "total_skb={rx={bytes=%llu, "
"packets=%llu}, "
"tx={bytes=%llu, "
"packets=%llu}}, "
@@ -198,10 +202,14 @@ char *pp_iface_stat(struct iface_stat *is)
"tag_stat_tree=rb_root{...}}",
is,
is->ifname,
- is->totals[IFS_RX].bytes,
- is->totals[IFS_RX].packets,
- is->totals[IFS_TX].bytes,
- is->totals[IFS_TX].packets,
+ is->totals_via_dev[IFS_RX].bytes,
+ is->totals_via_dev[IFS_RX].packets,
+ is->totals_via_dev[IFS_TX].bytes,
+ is->totals_via_dev[IFS_TX].packets,
+ is->totals_via_skb[IFS_RX].bytes,
+ is->totals_via_skb[IFS_RX].packets,
+ is->totals_via_skb[IFS_TX].bytes,
+ is->totals_via_skb[IFS_TX].packets,
is->last_known_valid,
is->last_known[IFS_RX].bytes,
is->last_known[IFS_RX].packets,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 7/7][RFC] netfilter: xt_IDLETIMER: Rename INTERFACE to LABEL in netlink notification.
From: John Stultz @ 2012-09-22 2:10 UTC (permalink / raw)
To: LKML; +Cc: Ashish Sharma, netdev, JP Abgrall, Peter P Waskiewicz Jr,
John Stultz
In-Reply-To: <1348279853-44499-1-git-send-email-john.stultz@linaro.org>
From: Ashish Sharma <ashishsharma@google.com>
Rename INTERFACE to LABEL in netlink notification.
Cc: netdev@vger.kernel.org
Cc: JP Abgrall <jpa@google.com>
Cc: Ashish Sharma <ashishsharma@google.com>
Cc: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Ashish Sharma <ashishsharma@google.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
net/netfilter/xt_IDLETIMER.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c
index df91e26..f4ba863 100644
--- a/net/netfilter/xt_IDLETIMER.c
+++ b/net/netfilter/xt_IDLETIMER.c
@@ -68,15 +68,15 @@ static DEFINE_MUTEX(list_mutex);
static struct kobject *idletimer_tg_kobj;
-static void notify_netlink_uevent(const char *iface, struct idletimer_tg *timer)
+static void notify_netlink_uevent(const char *label, struct idletimer_tg *timer)
{
- char iface_msg[NLMSG_MAX_SIZE];
+ char label_msg[NLMSG_MAX_SIZE];
char state_msg[NLMSG_MAX_SIZE];
- char *envp[] = { iface_msg, state_msg, NULL };
+ char *envp[] = { label_msg, state_msg, NULL };
int res;
- res = snprintf(iface_msg, NLMSG_MAX_SIZE, "INTERFACE=%s",
- iface);
+ res = snprintf(label_msg, NLMSG_MAX_SIZE, "LABEL=%s",
+ label);
if (NLMSG_MAX_SIZE <= res) {
pr_err("message too long (%d)", res);
return;
@@ -87,7 +87,7 @@ static void notify_netlink_uevent(const char *iface, struct idletimer_tg *timer)
pr_err("message too long (%d)", res);
return;
}
- pr_debug("putting nlmsg: <%s> <%s>\n", iface_msg, state_msg);
+ pr_debug("putting nlmsg: <%s> <%s>\n", label_msg, state_msg);
kobject_uevent_env(idletimer_tg_kobj, KOBJ_CHANGE, envp);
return;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 6/7][RFC] netfilter: xt_IDLETIMER: Add new netlink msg type
From: John Stultz @ 2012-09-22 2:10 UTC (permalink / raw)
To: LKML; +Cc: JP Abgrall, netdev, Ashish Sharma, Peter P Waskiewicz Jr,
John Stultz
In-Reply-To: <1348279853-44499-1-git-send-email-john.stultz@linaro.org>
From: JP Abgrall <jpa@google.com>
Send notifications when the label becomes active after an idle period.
Send netlink message notifications in addition to sysfs notifications.
Using a uevent with
subsystem=xt_idletimer
INTERFACE=...
STATE={active,inactive}
This is backport from common android-3.0
commit: beb914e987cbbd368988d2b94a6661cb907c4d5a
with uevent support instead of a new netlink message type.
Cc: netdev@vger.kernel.org
Cc: JP Abgrall <jpa@google.com>
Cc: Ashish Sharma <ashishsharma@google.com>
Cc: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Ashish Sharma <ashishsharma@google.com>
Signed-off-by: JP Abgrall <jpa@google.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
include/linux/netfilter/xt_IDLETIMER.h | 8 ++++
net/netfilter/xt_IDLETIMER.c | 78 +++++++++++++++++++++++++++++---
2 files changed, 79 insertions(+), 7 deletions(-)
diff --git a/include/linux/netfilter/xt_IDLETIMER.h b/include/linux/netfilter/xt_IDLETIMER.h
index 208ae93..faaa28b 100644
--- a/include/linux/netfilter/xt_IDLETIMER.h
+++ b/include/linux/netfilter/xt_IDLETIMER.h
@@ -4,6 +4,7 @@
* Header file for Xtables timer target module.
*
* Copyright (C) 2004, 2010 Nokia Corporation
+ *
* Written by Timo Teras <ext-timo.teras@nokia.com>
*
* Converted to x_tables and forward-ported to 2.6.34
@@ -32,12 +33,19 @@
#include <linux/types.h>
#define MAX_IDLETIMER_LABEL_SIZE 28
+#define NLMSG_MAX_SIZE 64
+
+#define NL_EVENT_TYPE_INACTIVE 0
+#define NL_EVENT_TYPE_ACTIVE 1
struct idletimer_tg_info {
__u32 timeout;
char label[MAX_IDLETIMER_LABEL_SIZE];
+ /* Use netlink messages for notification in addition to sysfs */
+ __u8 send_nl_msg;
+
/* for kernel module internal use only */
struct idletimer_tg *timer __attribute__((aligned(8)));
};
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c
index f407ebc1..df91e26 100644
--- a/net/netfilter/xt_IDLETIMER.c
+++ b/net/netfilter/xt_IDLETIMER.c
@@ -5,6 +5,7 @@
* After timer expires a kevent will be sent.
*
* Copyright (C) 2004, 2010 Nokia Corporation
+ *
* Written by Timo Teras <ext-timo.teras@nokia.com>
*
* Converted to x_tables and reworked for upstream inclusion
@@ -38,8 +39,10 @@
#include <linux/netfilter/xt_IDLETIMER.h>
#include <linux/kdev_t.h>
#include <linux/kobject.h>
+#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/sysfs.h>
+#include <net/net_namespace.h>
struct idletimer_tg_attr {
struct attribute attr;
@@ -56,6 +59,8 @@ struct idletimer_tg {
struct idletimer_tg_attr attr;
unsigned int refcnt;
+ bool send_nl_msg;
+ bool active;
};
static LIST_HEAD(idletimer_tg_list);
@@ -63,6 +68,32 @@ static DEFINE_MUTEX(list_mutex);
static struct kobject *idletimer_tg_kobj;
+static void notify_netlink_uevent(const char *iface, struct idletimer_tg *timer)
+{
+ char iface_msg[NLMSG_MAX_SIZE];
+ char state_msg[NLMSG_MAX_SIZE];
+ char *envp[] = { iface_msg, state_msg, NULL };
+ int res;
+
+ res = snprintf(iface_msg, NLMSG_MAX_SIZE, "INTERFACE=%s",
+ iface);
+ if (NLMSG_MAX_SIZE <= res) {
+ pr_err("message too long (%d)", res);
+ return;
+ }
+ res = snprintf(state_msg, NLMSG_MAX_SIZE, "STATE=%s",
+ timer->active ? "active" : "inactive");
+ if (NLMSG_MAX_SIZE <= res) {
+ pr_err("message too long (%d)", res);
+ return;
+ }
+ pr_debug("putting nlmsg: <%s> <%s>\n", iface_msg, state_msg);
+ kobject_uevent_env(idletimer_tg_kobj, KOBJ_CHANGE, envp);
+ return;
+
+
+}
+
static
struct idletimer_tg *__idletimer_tg_find_by_label(const char *label)
{
@@ -83,6 +114,7 @@ static ssize_t idletimer_tg_show(struct kobject *kobj, struct attribute *attr,
{
struct idletimer_tg *timer;
unsigned long expires = 0;
+ unsigned long now = jiffies;
mutex_lock(&list_mutex);
@@ -92,11 +124,15 @@ static ssize_t idletimer_tg_show(struct kobject *kobj, struct attribute *attr,
mutex_unlock(&list_mutex);
- if (time_after(expires, jiffies))
+ if (time_after(expires, now))
return sprintf(buf, "%u\n",
- jiffies_to_msecs(expires - jiffies) / 1000);
+ jiffies_to_msecs(expires - now) / 1000);
- return sprintf(buf, "0\n");
+ if (timer->send_nl_msg)
+ return sprintf(buf, "0 %d\n",
+ jiffies_to_msecs(now - expires) / 1000);
+ else
+ return sprintf(buf, "0\n");
}
static void idletimer_tg_work(struct work_struct *work)
@@ -105,6 +141,9 @@ static void idletimer_tg_work(struct work_struct *work)
work);
sysfs_notify(idletimer_tg_kobj, NULL, timer->attr.attr.name);
+
+ if (timer->send_nl_msg)
+ notify_netlink_uevent(timer->attr.attr.name, timer);
}
static void idletimer_tg_expired(unsigned long data)
@@ -113,6 +152,7 @@ static void idletimer_tg_expired(unsigned long data)
pr_debug("timer %s expired\n", timer->attr.attr.name);
+ timer->active = false;
schedule_work(&timer->work);
}
@@ -145,6 +185,8 @@ static int idletimer_tg_create(struct idletimer_tg_info *info)
setup_timer(&info->timer->timer, idletimer_tg_expired,
(unsigned long) info->timer);
info->timer->refcnt = 1;
+ info->timer->send_nl_msg = (info->send_nl_msg == 0) ? false : true;
+ info->timer->active = true;
mod_timer(&info->timer->timer,
msecs_to_jiffies(info->timeout * 1000) + jiffies);
@@ -168,14 +210,24 @@ static unsigned int idletimer_tg_target(struct sk_buff *skb,
const struct xt_action_param *par)
{
const struct idletimer_tg_info *info = par->targinfo;
+ unsigned long now = jiffies;
pr_debug("resetting timer %s, timeout period %u\n",
info->label, info->timeout);
BUG_ON(!info->timer);
+ info->timer->active = true;
+
+ if (time_before(info->timer->timer.expires, now)) {
+ schedule_work(&info->timer->work);
+ pr_debug("Starting timer %s (Expired, Jiffies): %lu, %lu\n",
+ info->label, info->timer->timer.expires, now);
+ }
+
+ /* TODO: Avoid modifying timers on each packet */
mod_timer(&info->timer->timer,
- msecs_to_jiffies(info->timeout * 1000) + jiffies);
+ msecs_to_jiffies(info->timeout * 1000) + now);
return XT_CONTINUE;
}
@@ -184,8 +236,9 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par)
{
struct idletimer_tg_info *info = par->targinfo;
int ret;
+ unsigned long now = jiffies;
- pr_debug("checkentry targinfo%s\n", info->label);
+ pr_debug("checkentry targinfo %s\n", info->label);
if (info->timeout == 0) {
pr_debug("timeout value is zero\n");
@@ -204,8 +257,16 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par)
info->timer = __idletimer_tg_find_by_label(info->label);
if (info->timer) {
info->timer->refcnt++;
+ info->timer->active = true;
+
+ if (time_before(info->timer->timer.expires, now)) {
+ schedule_work(&info->timer->work);
+ pr_debug("Starting Checkentry timer (Expired, Jiffies): %lu, %lu\n",
+ info->timer->timer.expires, now);
+ }
+
mod_timer(&info->timer->timer,
- msecs_to_jiffies(info->timeout * 1000) + jiffies);
+ msecs_to_jiffies(info->timeout * 1000) + now);
pr_debug("increased refcnt of timer %s to %u\n",
info->label, info->timer->refcnt);
@@ -219,6 +280,7 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par)
}
mutex_unlock(&list_mutex);
+
return 0;
}
@@ -240,7 +302,7 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par)
kfree(info->timer);
} else {
pr_debug("decreased refcnt of timer %s to %u\n",
- info->label, info->timer->refcnt);
+ info->label, info->timer->refcnt);
}
mutex_unlock(&list_mutex);
@@ -248,6 +310,7 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par)
static struct xt_target idletimer_tg __read_mostly = {
.name = "IDLETIMER",
+ .revision = 1,
.family = NFPROTO_UNSPEC,
.target = idletimer_tg_target,
.targetsize = sizeof(struct idletimer_tg_info),
@@ -313,3 +376,4 @@ MODULE_DESCRIPTION("Xtables: idle time monitor");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("ipt_IDLETIMER");
MODULE_ALIAS("ip6t_IDLETIMER");
+MODULE_ALIAS("arpt_IDLETIMER");
--
1.7.9.5
^ permalink raw reply related
* [PATCH] net/phy/bcm87xx: Add MODULE_LICENSE("GPL") to GPL driver
From: Peter Huewe @ 2012-09-22 2:44 UTC (permalink / raw)
To: David S. Miller
Cc: Peter Korsgaard, David Daney, Christian Hohnstaedt, netdev,
linux-kernel, Peter Huewe, stable
Currently the driver has no MODULE_LICENSE attribute in its source which
results in a kernel taint if I load this:
root@(none):~# modprobe bcm87xx
bcm87xx: module license 'unspecified' taints kernel.
Since the first lines of the source code clearly state:
* This file is subject to the terms and conditions of the GNU General
* Public License. See the file "COPYING" in the main directory of this
* archive for more details.
I think it's safe to add the MODULE_LICENSE("GPL") macro and thus remove
the kernel taint.
Cc: stable@vger.kernel.org
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
---
drivers/net/phy/bcm87xx.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c
index 2346b38..7997895 100644
--- a/drivers/net/phy/bcm87xx.c
+++ b/drivers/net/phy/bcm87xx.c
@@ -229,3 +229,5 @@ static void __exit bcm87xx_exit(void)
ARRAY_SIZE(bcm87xx_driver));
}
module_exit(bcm87xx_exit);
+
+MODULE_LICENSE("GPL");
--
1.7.8.6
^ permalink raw reply related
* Re: multicast, interfaces, kernel 3.0+...
From: Michael Tokarev @ 2012-09-22 4:21 UTC (permalink / raw)
To: netdev
In-Reply-To: <505CB607.7080207@msgid.tls.msk.ru>
On 21.09.2012 22:46, Michael Tokarev wrote:
> Hello.
>
> We found some, well, interesting behavour of kernels
> 3.0 and later, while 2.6.32 (previous long-stable
> series) worked fine. I'm not sure when it "broke",
> since this is a production machine and we've difficult
> time diagnosing it, and the app causing it is, well,
> large.
>
> The short story. A big java app uses multicast group
> to register one component and find it later.
>
> The machine in question has 3 active network interfaces:
> usual lo, eth0, and virtual (tap, pointopoint) tinc.
> Tinc interface is marked as "multicast off".
>
> When the app starts on 2.6.32 kernel, netstat -g shows
> that multicast group on 2 interfaces: lo and eth0, but
> not on tinc, which is sort of expected:
>
> $ netstat -g
> IPv6/IPv4 Group Memberships
> Interface RefCnt Group
> --------------- ------ ---------------------
> lo 4 228.5.6.7
> lo 1 all-systems.mcast.net
> eth0 4 228.5.6.7
> eth0 1 all-systems.mcast.net
> tinc 1 all-systems.mcast.net
>
>
> But when the same app (actually the same userspace) is
> booted on the same machine but on 3.0+ kernel, the same
> multicast group is registered also on 2 interfaces, but
> this time these are lo (as before) and tinc, but not eth0:
>
> $ netstat -g
> IPv6/IPv4 Group Memberships
> Interface RefCnt Group
> --------------- ------ ---------------------
> lo 4 228.5.6.7
> lo 1 all-systems.mcast.net
> eth0 1 all-systems.mcast.net
> tinc 4 228.5.6.7
> tinc 1 all-systems.mcast.net
>
> Now, on 3.0+ kernel, parts of this app can't find each
> other. The "client" tries to send a datagram packet
> to this address, 228.5.6.7, but receives no reply.
>
> On 2.6.32 kernel, when eth0 is used instead of tinc,
> it all works as expected.
Now this is interesting, questionable, and is a change
in behavour, albiet, well, again, questionable ;)
I looked at straces, and found this.
The app looks at all interfaces on the host, and for
each interface found, it calls IP_ADD_MEMBERSHIP.
But.
On this machine, for years, we had the same address on
eth0 and on tinc interfaces (that's long story).
Now, the difference in behavour between 3.0+ and 2.6.32
is that for this one IP address, corresponding IP_ADD_MEMBERSHIP
call on one kernel adds one iface to the group, while on
another kernel it is another iface. That's the whole
difference.
Why I said it is a "questionable question". The IP_ADD_MEMBERSHIP
interface is apparently misdefined, because it accepts an
IP address of an interface, instead of an ifindex, or
ifname, or something like this, since there's no, obviously,
1:1 correspondence between ifaces and addresses, an iface
can have no addresses assotiated with it, or two ifaces can
share one IP address like in my case. But the "questionable"
part is the "usualness" of this setup I have here, with two
ifaces having the same IP address.
I've no idea why the app does this thing to start with,
why it can't use wildcard address with IP_ADD_MEMBERSHIP,
or why it messes with that stuff at all. It is a different
question.
So, should IP_ADD_MEMBERSHIP use some more iface-centric
interface, instead of relying on IP addresses? And why
3.0+ changed order here?
Thanks!
/mjt
^ permalink raw reply
* Re: multicast, interfaces, kernel 3.0+...
From: David Miller @ 2012-09-22 4:31 UTC (permalink / raw)
To: mjt; +Cc: netdev
In-Reply-To: <505D3CE0.2050603@msgid.tls.msk.ru>
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Sat, 22 Sep 2012 08:21:52 +0400
> The IP_ADD_MEMBERSHIP interface is apparently misdefined, because it
> accepts an IP address of an interface, instead of an ifindex, or
> ifname, or something like this, since there's no, obviously, 1:1
> correspondence between ifaces and addresses, an iface can have no
> addresses assotiated with it, or two ifaces can share one IP address
> like in my case. But the "questionable" part is the "usualness" of
> this setup I have here, with two ifaces having the same IP address.
Can you at least look at the API specification for IP_ADD_MEMBERSHIP
before making such claims?
The IP_ADD_MEMBERSHIP interface allows for the specification of a
specific interface, the structure you pass into IP_ADD_MEMBERSHIP has
an ->imr_ifindex field and this is the first key the call uses
to pick a device.
If you do not specify an explicit ifindex, and leave it at zero which
I bet your application is doing, it picks the first address which has
the specified address.
As you have discovered, just specifying the address can cause unwanted
effects when multiple devices have the same IP address. Because the
order of network devices in the system is never, and has never, been
guaranteed.
So the selection in this situation is essentially random because
you haven't given the kernel enough information to choose things
the way that you want it to.
^ permalink raw reply
* Re: multicast, interfaces, kernel 3.0+...
From: Michael Tokarev @ 2012-09-22 4:43 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120922.003133.2272531217856660981.davem@davemloft.net>
On 22.09.2012 08:31, David Miller wrote:
> From: Michael Tokarev <mjt@tls.msk.ru>
> Date: Sat, 22 Sep 2012 08:21:52 +0400
>
>> The IP_ADD_MEMBERSHIP interface is apparently misdefined, because it
>> accepts an IP address of an interface, instead of an ifindex, or
>> ifname, or something like this, since there's no, obviously, 1:1
>> correspondence between ifaces and addresses, an iface can have no
>> addresses assotiated with it, or two ifaces can share one IP address
>> like in my case. But the "questionable" part is the "usualness" of
>> this setup I have here, with two ifaces having the same IP address.
>
> Can you at least look at the API specification for IP_ADD_MEMBERSHIP
> before making such claims?
As I mentioned in previous email, I haven't dealt with multicast before,
so obviously I tried my best to learn before making any claims at all.
And the fine manual, http://tldp.org/HOWTO/Multicast-HOWTO-6.html ,
says:
6.4 IP_ADD_MEMBERSHIP.
The ip_mreq structure (taken from /usr/include/linux/in.h) has the following members:
struct ip_mreq
{
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
};
...
setsockopt (socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
Yes I probably should have read the mentioned header and the manpage too.
But the app does this:
setsockopt(567, SOL_IP, IP_ADD_MEMBERSHIP, "\344\5\6\7\nM\7Z", 8) = 0
setsockopt(567, SOL_IP, IP_ADD_MEMBERSHIP, "\344\5\6\7\nM\7Z", 8) = -1 EADDRINUSE (Address already in use)
so apparently sizeof(mreq) is 8 bytes for it, and I just didn't think there
may be additional fields in "real life". That was puzzling, so I asked.
(This is most likely a generic java interface to this facility, not
linux-specific).
As you can see, I at least tried. It wasn't apparently successful, but
that isn't entirely my fault either, -- the "canonical" howto does not
mention that there might be more members in this structure.. ;)
> The IP_ADD_MEMBERSHIP interface allows for the specification of a
> specific interface, the structure you pass into IP_ADD_MEMBERSHIP has
> an ->imr_ifindex field and this is the first key the call uses
> to pick a device.
Ok, after you mentioned this, I looked at the other sources and indeed
it has. I stand corrected, and my questions answered.
> If you do not specify an explicit ifindex, and leave it at zero which
> I bet your application is doing, it picks the first address which has
> the specified address.
>
> As you have discovered, just specifying the address can cause unwanted
> effects when multiple devices have the same IP address. Because the
> order of network devices in the system is never, and has never, been
> guaranteed.
>
> So the selection in this situation is essentially random because
> you haven't given the kernel enough information to choose things
> the way that you want it to.
Yes, that's what I thought too, it was just puzzling with the missing
bits of info. And yes I remember when order of addresses changed
in various places (routing table was one example) and people started
complaining, even when order had never been deterministic.
I'm not complaining, I'm just asking. And you answered my questions
perfectly, thank you!
/mjt
^ permalink raw reply
* Re: multicast, interfaces, kernel 3.0+...
From: David Miller @ 2012-09-22 4:47 UTC (permalink / raw)
To: mjt; +Cc: netdev
In-Reply-To: <505D41DB.7060508@msgid.tls.msk.ru>
From: Michael Tokarev <mjt@tls.msk.ru>
Date: Sat, 22 Sep 2012 08:43:07 +0400
> And the fine manual, http://tldp.org/HOWTO/Multicast-HOWTO-6.html ,
You're reading a document that's 14 years old.
^ permalink raw reply
* Re: multicast, interfaces, kernel 3.0+...
From: David Miller @ 2012-09-22 4:50 UTC (permalink / raw)
To: mjt; +Cc: netdev
In-Reply-To: <20120922.004712.758145747373586331.davem@davemloft.net>
BTW, your site must be in a huge number of anti SPAM databases.
Because every time a mail is sent in this thread, as vger.kernel.org
postmaster I see hundreds of subscribers bounce.
It only happens for postings where your email address appears.
So you are basically invisible to much of the world, just FYI.
^ permalink raw reply
* Re: [PATCH net-next 3/3] ptp: derive the device name from the parent device
From: Richard Cochran @ 2012-09-22 5:43 UTC (permalink / raw)
To: Ben Hutchings
Cc: Keller, Jacob E, netdev@vger.kernel.org, David Miller,
Kirsher, Jeffrey T, John Stultz, Vick, Matthew
In-Reply-To: <1348254106.2521.56.camel@bwh-desktop.uk.solarflarecom.com>
On Fri, Sep 21, 2012 at 08:01:46PM +0100, Ben Hutchings wrote:
>
> The ethtool command is useful but setting the parent device may be even
> more useful, e.g. you will be able to write udev rules for PHC devices
> based on the parent device's identity.
Thinking about this a bit more, it makes no sense to put the parent
device name into clock_name, because that information is redundant.
# ls -l /sys/class/ptp/ptp0/
-r--r--r-- 1 root root 8192 Jan 1 00:00 clock_name
-r--r--r-- 1 root root 8192 Jan 1 00:00 dev
lrwxrwxrwx 1 root root 0 Jan 1 00:00 device -> ../../../fec-1:01
I agree that the parent device is useful, and I will add it. However,
I will leave the clock_name as it is, adding a bit more prose to the
ABI description.
The one case where clock_name becomes really important is when you
have a PHY clock, like in the above example, since it provides a way
to see that the clock is *not* related to the MAC.
Thanks,
Richard
^ permalink raw reply
* Re: [PATCH net-next 3/3] ptp: derive the device name from the parent device
From: Richard Cochran @ 2012-09-22 5:46 UTC (permalink / raw)
To: Ben Hutchings
Cc: Keller, Jacob E, netdev@vger.kernel.org, David Miller,
Kirsher, Jeffrey T, John Stultz, Vick, Matthew
In-Reply-To: <20120922054345.GA6124@netboy.at.omicron.at>
On Sat, Sep 22, 2012 at 07:43:46AM +0200, Richard Cochran wrote:
>
> The one case where clock_name becomes really important is when you
> have a PHY clock, like in the above example, since it provides a way
> to see that the clock is *not* related to the MAC.
I mean that a PHY clock is not a part of the MAC. Of course it is
related to the MAC by virtue of being connected to it via a MDIO bus.
Thanks,
Richard
^ permalink raw reply
* Re: Possible networking regression in 3.6.0
From: Chris Clayton @ 2012-09-22 6:26 UTC (permalink / raw)
To: Chris Clayton; +Cc: Eric Dumazet, netdev
In-Reply-To: <5059E40C.4070607@googlemail.com>
I guess you network developer folks are either very busy or this
regression is proving a bit troublesome to identify, so I've opened a
bugzilla report to keep track of it. The report number is 47761.
Chris
On 09/19/12 16:26, Chris Clayton wrote:
>>
>> It would help to have some traffic sample, maybe.
>>
>> Especially if the problem is not easily reproductible for us.
>>
>
> OK, I've used an netsniff-ng to capture the traffic on all interfaces on
> the host (that would be tap0 and eth0, I guess) whilst attempting to
> ping the router from the WinXP KVM client. The result is a pcap file
> that I processed with tcpdump to produce:
>
> reading from file net-trace.pcap, link-type EN10MB (Ethernet)
> 14:56:31.406336 ARP, Request who-has 192.168.200.254 tell 192.168.200.1,
> length 28
> 0x0000: 0001 0800 0604 0001 5254 0c3b 1728 c0a8
> 0x0010: c801 0000 0000 0000 c0a8 c8fe
> 14:56:31.406357 ARP, Reply 192.168.200.254 is-at 46:83:93:8f:f0:7e,
> length 28
> 0x0000: 0001 0800 0604 0002 4683 938f f07e c0a8
> 0x0010: c8fe 5254 0c3b 1728 c0a8 c801
> 14:56:31.406534 IP 192.168.200.1 > 192.168.0.1: ICMP echo request, id
> 512, seq 4352, length 40
> 0x0000: 4500 003c 0195 0000 8001 efd8 c0a8 c801
> 0x0010: c0a8 0001 0800 3a5c 0200 1100 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:31.406566 ARP, Request who-has 192.168.0.1 tell 192.168.0.40,
> length 28
> 0x0000: 0001 0800 0604 0001 5c9a d85c 6331 c0a8
> 0x0010: 0028 0000 0000 0000 c0a8 0001
> 14:56:31.410830 ARP, Reply 192.168.0.1 is-at 00:1f:33:80:09:44, length 46
> 0x0000: 0001 0800 0604 0002 001f 3380 0944 c0a8
> 0x0010: 0001 5c9a d85c 6331 c0a8 0028 c0a8 0001
> 0x0020: e000 0001 1164 ee9b 0000 0000 4500
> 14:56:31.410851 IP 192.168.0.40 > 192.168.0.1: ICMP echo request, id
> 512, seq 4352, length 40
> 0x0000: 4500 003c 0195 0000 7f01 b8b2 c0a8 0028
> 0x0010: c0a8 0001 0800 3a5c 0200 1100 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:31.414474 IP 192.168.0.1 > 192.168.0.40: ICMP echo reply, id 512,
> seq 4352, length 40
> 0x0000: 4500 003c cf4f 0000 ff01 6af7 c0a8 0001
> 0x0010: c0a8 0028 0000 425c 0200 1100 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:36.404781 ARP, Request who-has 192.168.0.40 tell 192.168.0.1,
> length 46
> 0x0000: 0001 0800 0604 0001 001f 3380 0944 c0a8
> 0x0010: 0001 0000 0000 0000 c0a8 0028 c0a8 0001
> 0x0020: c0a8 0028 0000 425c 0200 1100 6162
> 14:56:36.404806 ARP, Reply 192.168.0.40 is-at 5c:9a:d8:5c:63:31, length 28
> 0x0000: 0001 0800 0604 0002 5c9a d85c 6331 c0a8
> 0x0010: 0028 001f 3380 0944 c0a8 0001
> 14:56:36.689750 IP 192.168.200.1 > 192.168.0.1: ICMP echo request, id
> 512, seq 4608, length 40
> 0x0000: 4500 003c 0196 0000 8001 efd7 c0a8 c801
> 0x0010: c0a8 0001 0800 395c 0200 1200 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:36.689774 IP 192.168.0.40 > 192.168.0.1: ICMP echo request, id
> 512, seq 4608, length 40
> 0x0000: 4500 003c 0196 0000 7f01 b8b1 c0a8 0028
> 0x0010: c0a8 0001 0800 395c 0200 1200 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:36.693330 IP 192.168.0.1 > 192.168.0.40: ICMP echo reply, id 512,
> seq 4608, length 40
> 0x0000: 4500 003c cf50 0000 ff01 6af6 c0a8 0001
> 0x0010: c0a8 0028 0000 415c 0200 1200 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:42.189424 IP 192.168.200.1 > 192.168.0.1: ICMP echo request, id
> 512, seq 4864, length 40
> 0x0000: 4500 003c 0197 0000 8001 efd6 c0a8 c801
> 0x0010: c0a8 0001 0800 385c 0200 1300 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:42.189447 IP 192.168.0.40 > 192.168.0.1: ICMP echo request, id
> 512, seq 4864, length 40
> 0x0000: 4500 003c 0197 0000 7f01 b8b0 c0a8 0028
> 0x0010: c0a8 0001 0800 385c 0200 1300 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:42.193029 IP 192.168.0.1 > 192.168.0.40: ICMP echo reply, id 512,
> seq 4864, length 40
> 0x0000: 4500 003c cf51 0000 ff01 6af5 c0a8 0001
> 0x0010: c0a8 0028 0000 405c 0200 1300 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:47.689414 IP 192.168.200.1 > 192.168.0.1: ICMP echo request, id
> 512, seq 5120, length 40
> 0x0000: 4500 003c 0198 0000 8001 efd5 c0a8 c801
> 0x0010: c0a8 0001 0800 375c 0200 1400 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:47.689439 IP 192.168.0.40 > 192.168.0.1: ICMP echo request, id
> 512, seq 5120, length 40
> 0x0000: 4500 003c 0198 0000 7f01 b8af c0a8 0028
> 0x0010: c0a8 0001 0800 375c 0200 1400 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
> 14:56:47.693661 IP 192.168.0.1 > 192.168.0.40: ICMP echo reply, id 512,
> seq 5120, length 40
> 0x0000: 4500 003c cf52 0000 ff01 6af4 c0a8 0001
> 0x0010: c0a8 0028 0000 3f5c 0200 1400 6162 6364
> 0x0020: 6566 6768 696a 6b6c 6d6e 6f70 7172 7374
> 0x0030: 7576 7761 6263 6465 6667 6869
>
> Is this what you asked for?
>
> Chris
>
^ permalink raw reply
* [PATCH V2 net-next 0/4] Two new PTP Hardware Clock features
From: Richard Cochran @ 2012-09-22 7:42 UTC (permalink / raw)
To: netdev
Cc: Ben Hutchings, David Miller, Jacob Keller, Jeff Kirsher,
John Stultz, Matthew Vick
This patch series adds two new features to the PHC code.
The first two patches let a user program find out the previously
dialed frequency adjustment. This is primarily useful when restarting
a PTP service, since without this information, the presumably correct
adjustment will bias the new frequency estimation.
The third patch links the phc class device to its parent device within
the driver model and sysfs.
The fourth patch adds a bit more documentation of the sysfs clock_name
attribute. This should help clarify the naming scheme.
Thanks,
Richard
Richard Cochran (4):
ptp: remember the adjusted frequency
ptp: provide the clock's adjusted frequency
ptp: link the phc device to its parent device
ptp: clarify the clock_name sysfs attribute
Documentation/ABI/testing/sysfs-ptp | 5 ++++-
drivers/net/ethernet/freescale/gianfar_ptp.c | 2 +-
drivers/net/ethernet/intel/igb/igb_ptp.c | 3 ++-
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 3 ++-
drivers/net/ethernet/sfc/ptp.c | 3 ++-
drivers/net/phy/dp83640.c | 2 +-
drivers/ptp/ptp_clock.c | 11 +++++++++--
drivers/ptp/ptp_ixp46x.c | 2 +-
drivers/ptp/ptp_pch.c | 2 +-
drivers/ptp/ptp_private.h | 1 +
include/linux/ptp_clock_kernel.h | 7 +++++--
11 files changed, 29 insertions(+), 12 deletions(-)
--
1.7.2.5
^ permalink raw reply
* [PATCH V2 net-next 1/4] ptp: remember the adjusted frequency
From: Richard Cochran @ 2012-09-22 7:42 UTC (permalink / raw)
To: netdev
Cc: Ben Hutchings, David Miller, Jacob Keller, Jeff Kirsher,
John Stultz, Matthew Vick
In-Reply-To: <cover.1348299094.git.richardcochran@gmail.com>
This patch adds a field to the representation of a PTP hardware clock in
order to remember the frequency adjustment value dialed by the user.
Adding this field will let us answer queries in the manner of adjtimex
in a follow on patch.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
drivers/ptp/ptp_clock.c | 1 +
drivers/ptp/ptp_private.h | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index 966875d..67e628e 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -147,6 +147,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
} else if (tx->modes & ADJ_FREQUENCY) {
err = ops->adjfreq(ops, scaled_ppm_to_ppb(tx->freq));
+ ptp->dialed_frequency = tx->freq;
}
return err;
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
index 4d5b508..69d3207 100644
--- a/drivers/ptp/ptp_private.h
+++ b/drivers/ptp/ptp_private.h
@@ -45,6 +45,7 @@ struct ptp_clock {
dev_t devid;
int index; /* index into clocks.map */
struct pps_device *pps_source;
+ long dialed_frequency; /* remembers the frequency adjustment */
struct timestamp_event_queue tsevq; /* simple fifo for time stamps */
struct mutex tsevq_mux; /* one process at a time reading the fifo */
wait_queue_head_t tsev_wq;
--
1.7.2.5
^ permalink raw reply related
* [PATCH V2 net-next 2/4] ptp: provide the clock's adjusted frequency
From: Richard Cochran @ 2012-09-22 7:42 UTC (permalink / raw)
To: netdev
Cc: Ben Hutchings, David Miller, Jacob Keller, Jeff Kirsher,
John Stultz, Matthew Vick
In-Reply-To: <cover.1348299094.git.richardcochran@gmail.com>
If the timex.mode field indicates a query, then we provide the value of
the current frequency adjustment.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
drivers/ptp/ptp_clock.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index 67e628e..6f7009a 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -148,6 +148,11 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
err = ops->adjfreq(ops, scaled_ppm_to_ppb(tx->freq));
ptp->dialed_frequency = tx->freq;
+
+ } else if (tx->modes == 0) {
+
+ tx->freq = ptp->dialed_frequency;
+ err = 0;
}
return err;
--
1.7.2.5
^ permalink raw reply related
* [PATCH V2 net-next 3/4] ptp: link the phc device to its parent device
From: Richard Cochran @ 2012-09-22 7:42 UTC (permalink / raw)
To: netdev
Cc: Ben Hutchings, David Miller, Jacob Keller, Jeff Kirsher,
John Stultz, Matthew Vick
In-Reply-To: <cover.1348299094.git.richardcochran@gmail.com>
PTP Hardware Clock devices appear as class devices in sysfs. This patch
changes the registration API to use the parent device, clarifying the
clock's relationship to the underlying device.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
drivers/net/ethernet/freescale/gianfar_ptp.c | 2 +-
drivers/net/ethernet/intel/igb/igb_ptp.c | 3 ++-
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 3 ++-
drivers/net/ethernet/sfc/ptp.c | 3 ++-
drivers/net/phy/dp83640.c | 2 +-
drivers/ptp/ptp_clock.c | 5 +++--
drivers/ptp/ptp_ixp46x.c | 2 +-
drivers/ptp/ptp_pch.c | 2 +-
include/linux/ptp_clock_kernel.h | 7 +++++--
9 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c
index c08e5d4..18762a3 100644
--- a/drivers/net/ethernet/freescale/gianfar_ptp.c
+++ b/drivers/net/ethernet/freescale/gianfar_ptp.c
@@ -510,7 +510,7 @@ static int gianfar_ptp_probe(struct platform_device *dev)
spin_unlock_irqrestore(&etsects->lock, flags);
- etsects->clock = ptp_clock_register(&etsects->caps);
+ etsects->clock = ptp_clock_register(&etsects->caps, &dev->dev);
if (IS_ERR(etsects->clock)) {
err = PTR_ERR(etsects->clock);
goto no_clock;
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index e13ba1d..ee21445 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -752,7 +752,8 @@ void igb_ptp_init(struct igb_adapter *adapter)
wr32(E1000_IMS, E1000_IMS_TS);
}
- adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps);
+ adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,
+ &adapter->pdev->dev);
if (IS_ERR(adapter->ptp_clock)) {
adapter->ptp_clock = NULL;
dev_err(&adapter->pdev->dev, "ptp_clock_register failed\n");
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 3456d56..39881cb 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -960,7 +960,8 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
/* (Re)start the overflow check */
adapter->flags2 |= IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED;
- adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps);
+ adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,
+ &adapter->pdev->dev);
if (IS_ERR(adapter->ptp_clock)) {
adapter->ptp_clock = NULL;
e_dev_err("ptp_clock_register failed\n");
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 2b07a4e..3ed5d13 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -931,7 +931,8 @@ static int efx_ptp_probe_channel(struct efx_channel *channel)
ptp->phc_clock_info.settime = efx_phc_settime;
ptp->phc_clock_info.enable = efx_phc_enable;
- ptp->phc_clock = ptp_clock_register(&ptp->phc_clock_info);
+ ptp->phc_clock = ptp_clock_register(&ptp->phc_clock_info,
+ &channel->napi_dev->dev);
if (!ptp->phc_clock)
goto fail3;
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index b0da022..24e05c4 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -980,7 +980,7 @@ static int dp83640_probe(struct phy_device *phydev)
if (choose_this_phy(clock, phydev)) {
clock->chosen = dp83640;
- clock->ptp_clock = ptp_clock_register(&clock->caps);
+ clock->ptp_clock = ptp_clock_register(&clock->caps, &phydev->dev);
if (IS_ERR(clock->ptp_clock)) {
err = PTR_ERR(clock->ptp_clock);
goto no_register;
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index 6f7009a..b15a376 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -186,7 +186,8 @@ static void delete_ptp_clock(struct posix_clock *pc)
/* public interface */
-struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info)
+struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
+ struct device *parent)
{
struct ptp_clock *ptp;
int err = 0, index, major = MAJOR(ptp_devt);
@@ -219,7 +220,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info)
init_waitqueue_head(&ptp->tsev_wq);
/* Create a new device in our class. */
- ptp->dev = device_create(ptp_class, NULL, ptp->devid, ptp,
+ ptp->dev = device_create(ptp_class, parent, ptp->devid, ptp,
"ptp%d", ptp->index);
if (IS_ERR(ptp->dev))
goto no_device;
diff --git a/drivers/ptp/ptp_ixp46x.c b/drivers/ptp/ptp_ixp46x.c
index e03c406..d49b851 100644
--- a/drivers/ptp/ptp_ixp46x.c
+++ b/drivers/ptp/ptp_ixp46x.c
@@ -298,7 +298,7 @@ static int __init ptp_ixp_init(void)
ixp_clock.caps = ptp_ixp_caps;
- ixp_clock.ptp_clock = ptp_clock_register(&ixp_clock.caps);
+ ixp_clock.ptp_clock = ptp_clock_register(&ixp_clock.caps, NULL);
if (IS_ERR(ixp_clock.ptp_clock))
return PTR_ERR(ixp_clock.ptp_clock);
diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c
index 3a9c17e..e624e4d 100644
--- a/drivers/ptp/ptp_pch.c
+++ b/drivers/ptp/ptp_pch.c
@@ -627,7 +627,7 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
chip->caps = ptp_pch_caps;
- chip->ptp_clock = ptp_clock_register(&chip->caps);
+ chip->ptp_clock = ptp_clock_register(&chip->caps, &pdev->dev);
if (IS_ERR(chip->ptp_clock))
return PTR_ERR(chip->ptp_clock);
diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
index a644b29..56c71b2 100644
--- a/include/linux/ptp_clock_kernel.h
+++ b/include/linux/ptp_clock_kernel.h
@@ -21,6 +21,7 @@
#ifndef _PTP_CLOCK_KERNEL_H_
#define _PTP_CLOCK_KERNEL_H_
+#include <linux/device.h>
#include <linux/pps_kernel.h>
#include <linux/ptp_clock.h>
@@ -93,10 +94,12 @@ struct ptp_clock;
/**
* ptp_clock_register() - register a PTP hardware clock driver
*
- * @info: Structure describing the new clock.
+ * @info: Structure describing the new clock.
+ * @parent: Pointer to the parent device of the new clock.
*/
-extern struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info);
+extern struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
+ struct device *parent);
/**
* ptp_clock_unregister() - unregister a PTP hardware clock driver
--
1.7.2.5
^ permalink raw reply related
* [PATCH V2 net-next 4/4] ptp: clarify the clock_name sysfs attribute
From: Richard Cochran @ 2012-09-22 7:42 UTC (permalink / raw)
To: netdev
Cc: Ben Hutchings, David Miller, Jacob Keller, Jeff Kirsher,
John Stultz, Matthew Vick
In-Reply-To: <cover.1348299094.git.richardcochran@gmail.com>
There has been some confusion among PHC driver authors about the
intended purpose of the clock_name attribute. This patch expands the
documation in order to clarify how the clock_name field should be
understood.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
Documentation/ABI/testing/sysfs-ptp | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-ptp b/Documentation/ABI/testing/sysfs-ptp
index d40d2b5..c906488 100644
--- a/Documentation/ABI/testing/sysfs-ptp
+++ b/Documentation/ABI/testing/sysfs-ptp
@@ -19,7 +19,10 @@ Date: September 2010
Contact: Richard Cochran <richardcochran@gmail.com>
Description:
This file contains the name of the PTP hardware clock
- as a human readable string.
+ as a human readable string. The purpose of this
+ attribute is to provide the user with a "friendly
+ name" and to help distinguish PHY based devices from
+ MAC based ones.
What: /sys/class/ptp/ptpN/max_adjustment
Date: September 2010
--
1.7.2.5
^ permalink raw reply related
* Re: [PATCH V2 net-next 0/4] Two new PTP Hardware Clock features
From: Richard Cochran @ 2012-09-22 7:45 UTC (permalink / raw)
To: netdev
Cc: Ben Hutchings, David Miller, Jacob Keller, Jeff Kirsher,
John Stultz, Matthew Vick
In-Reply-To: <cover.1348299094.git.richardcochran@gmail.com>
On Sat, Sep 22, 2012 at 09:42:52AM +0200, Richard Cochran wrote:
> This patch series adds two new features to the PHC code.
Forgot to say:
V2 preserves the clock_name attribute as it was meant to be, instead
of making any changes to it.
Thanks,
Richard
^ permalink raw reply
* Re: [PATCH net-next v1] net: use a per task frag allocator
From: Eric Dumazet @ 2012-09-21 21:11 UTC (permalink / raw)
To: Vijay Subramanian
Cc: David Miller, linux-kernel, netdev, Ben Hutchings,
Alexander Duyck
In-Reply-To: <CAGK4HS98RG78Auvaai3Ny6zz5c_hccO-ShD3GuT=moRRm4+RUA@mail.gmail.com>
On Fri, 2012-09-21 at 13:27 -0700, Vijay Subramanian wrote:
> I get the following compile error with the newer version of the patch
>
> net/sched/em_meta.c: In function ‘meta_int_sk_sendmsg_off’:
> net/sched/em_meta.c:464: error: ‘struct sock’ has no member named
> ‘sk_sndmsg_off’
> make[1]: *** [net/sched/em_meta.o] Error 1
> make: *** [net/sched/em_meta.o] Error 2
>
>
>
> Vijay
Oh well, I wonder what's the expected use of this crap...
Thanks, I'll fix this on v3 !
^ permalink raw reply
* Re: [PATCH V2 net-next 0/4] Two new PTP Hardware Clock features
From: Richard Cochran @ 2012-09-22 9:11 UTC (permalink / raw)
To: netdev
Cc: Ben Hutchings, David Miller, Jacob Keller, Jeff Kirsher,
John Stultz, Matthew Vick
In-Reply-To: <20120922074553.GA4143@netboy.at.omicron.at>
On Sat, Sep 22, 2012 at 09:45:53AM +0200, Richard Cochran wrote:
> On Sat, Sep 22, 2012 at 09:42:52AM +0200, Richard Cochran wrote:
> > This patch series adds two new features to the PHC code.
>
> Forgot to say:
>
> V2 preserves the clock_name attribute as it was meant to be, instead
> of making any changes to it.
... and covers the registration API change in the brand new solarflare
phc device, which was overlooked in V1.
Thanks,
Richard
^ permalink raw reply
* Warning! Your mailbox is almost full.
From: Webmail Account Upgrade @ 2012-09-22 8:35 UTC (permalink / raw)
You have exceeded your email limit quota of 450MB. You need to upgrade
your email limit quota to 2GB within the next 48 hours. Use the below
web link to upgrade your email account:
click link below:
http://www.formchamp.com/goform.php?id=38467
Thank you for using our email.
Copyright ©2012 Email Helpdesk Centre.
----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.
^ permalink raw reply
* [PATCH] pppoe: drop PPPOX_ZOMBIEs in pppoe_release
From: Xiaodong Xu @ 2012-09-22 9:53 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev
From: Xiaodong Xu <stid.smth@gmail.com>
When PPPOE is running over a virtual ethernet interface (e.g., a
bonding interface) and the user tries to delete the interface in case
the PPPOE state is ZOMBIE, the kernel will loop forever while
unregistering net_device for the reference count is not decreased to
zero which should have been done with dev_put().
Signed-off-by: Xiaodong Xu <stid.smth@gmail.com>
---
--- drivers/net/ppp/pppoe.c.orig 2012-09-19 11:49:27.921826868 +0800
+++ drivers/net/ppp/pppoe.c 2012-09-22 17:44:03.642730082 +0800
@@ -570,7 +570,7 @@ static int pppoe_release(struct socket *
po = pppox_sk(sk);
- if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+ if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
dev_put(po->pppoe_dev);
po->pppoe_dev = NULL;
}
--
Regards,
Xiaodong Xu
^ permalink raw reply
* [PATCH] ipv4: raw: fix icmp_filter()
From: Eric Dumazet @ 2012-09-22 10:08 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
icmp_filter() should not modify its input, or else its caller
would need to recompute ip_hdr() if skb->head is reallocated.
Use skb_header_pointer() instead of pskb_may_pull() and
change the prototype to make clear both sk and skb are const.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
This is a minimal fix, to meet stable expectations.
net/ipv4/raw.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index ff0f071..d23c657 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -131,18 +131,20 @@ found:
* 0 - deliver
* 1 - block
*/
-static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
+static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
{
- int type;
+ struct icmphdr _hdr;
+ const struct icmphdr *hdr;
- if (!pskb_may_pull(skb, sizeof(struct icmphdr)))
+ hdr = skb_header_pointer(skb, skb_transport_offset(skb),
+ sizeof(_hdr), &_hdr);
+ if (!hdr)
return 1;
- type = icmp_hdr(skb)->type;
- if (type < 32) {
+ if (hdr->type < 32) {
__u32 data = raw_sk(sk)->filter.data;
- return ((1 << type) & data) != 0;
+ return ((1U << hdr->type) & data) != 0;
}
/* Do not block unknown ICMP types */
^ 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