diff options
author | Murali Karicheri <m-karicheri2@ti.com> | 2019-04-05 13:31:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-06 21:32:21 -0400 |
commit | fc4ecaeebd26c77d463c898d9dd3edee234e371c (patch) | |
tree | 3114abdabf9661b7cd77c162f2d5a254f46b7091 | |
parent | 0e7623bdf34fff6587f96c27132aebe8c585631d (diff) |
net: hsr: add debugfs support for display node list
This adds a debugfs interface to allow display the nodes learned
by the hsr master.
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/hsr/Makefile | 1 | ||||
-rw-r--r-- | net/hsr/hsr_device.c | 5 | ||||
-rw-r--r-- | net/hsr/hsr_framereg.c | 12 | ||||
-rw-r--r-- | net/hsr/hsr_framereg.h | 12 | ||||
-rw-r--r-- | net/hsr/hsr_main.h | 17 | ||||
-rw-r--r-- | net/hsr/hsr_prp_debugfs.c | 120 |
6 files changed, 155 insertions, 12 deletions
diff --git a/net/hsr/Makefile b/net/hsr/Makefile index 9ae972a820f4..d74d89d013b0 100644 --- a/net/hsr/Makefile +++ b/net/hsr/Makefile | |||
@@ -6,3 +6,4 @@ obj-$(CONFIG_HSR) += hsr.o | |||
6 | 6 | ||
7 | hsr-y := hsr_main.o hsr_framereg.o hsr_device.o \ | 7 | hsr-y := hsr_main.o hsr_framereg.o hsr_device.o \ |
8 | hsr_netlink.o hsr_slave.o hsr_forward.o | 8 | hsr_netlink.o hsr_slave.o hsr_forward.o |
9 | hsr-$(CONFIG_DEBUG_FS) += hsr_prp_debugfs.o | ||
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index bb7bf2002040..b47a621e3f4e 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c | |||
@@ -354,6 +354,8 @@ static void hsr_dev_destroy(struct net_device *hsr_dev) | |||
354 | 354 | ||
355 | hsr = netdev_priv(hsr_dev); | 355 | hsr = netdev_priv(hsr_dev); |
356 | 356 | ||
357 | hsr_prp_debugfs_term(hsr); | ||
358 | |||
357 | rtnl_lock(); | 359 | rtnl_lock(); |
358 | hsr_for_each_port(hsr, port) | 360 | hsr_for_each_port(hsr, port) |
359 | hsr_del_port(port); | 361 | hsr_del_port(port); |
@@ -483,6 +485,9 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], | |||
483 | goto fail; | 485 | goto fail; |
484 | 486 | ||
485 | mod_timer(&hsr->prune_timer, jiffies + msecs_to_jiffies(PRUNE_PERIOD)); | 487 | mod_timer(&hsr->prune_timer, jiffies + msecs_to_jiffies(PRUNE_PERIOD)); |
488 | res = hsr_prp_debugfs_init(hsr); | ||
489 | if (res) | ||
490 | goto fail; | ||
486 | 491 | ||
487 | return 0; | 492 | return 0; |
488 | 493 | ||
diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index 22203562821f..a3cc30ac8a5a 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c | |||
@@ -18,18 +18,6 @@ | |||
18 | #include "hsr_framereg.h" | 18 | #include "hsr_framereg.h" |
19 | #include "hsr_netlink.h" | 19 | #include "hsr_netlink.h" |
20 | 20 | ||
21 | struct hsr_node { | ||
22 | struct list_head mac_list; | ||
23 | unsigned char macaddress_A[ETH_ALEN]; | ||
24 | unsigned char macaddress_B[ETH_ALEN]; | ||
25 | /* Local slave through which AddrB frames are received from this node */ | ||
26 | enum hsr_port_type addr_B_port; | ||
27 | unsigned long time_in[HSR_PT_PORTS]; | ||
28 | bool time_in_stale[HSR_PT_PORTS]; | ||
29 | u16 seq_out[HSR_PT_PORTS]; | ||
30 | struct rcu_head rcu_head; | ||
31 | }; | ||
32 | |||
33 | /* TODO: use hash lists for mac addresses (linux/jhash.h)? */ | 21 | /* TODO: use hash lists for mac addresses (linux/jhash.h)? */ |
34 | 22 | ||
35 | /* seq_nr_after(a, b) - return true if a is after (higher in sequence than) b, | 23 | /* seq_nr_after(a, b) - return true if a is after (higher in sequence than) b, |
diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h index 5f515d4cd088..a3bdcdab469d 100644 --- a/net/hsr/hsr_framereg.h +++ b/net/hsr/hsr_framereg.h | |||
@@ -48,4 +48,16 @@ int hsr_get_node_data(struct hsr_priv *hsr, | |||
48 | int *if2_age, | 48 | int *if2_age, |
49 | u16 *if2_seq); | 49 | u16 *if2_seq); |
50 | 50 | ||
51 | struct hsr_node { | ||
52 | struct list_head mac_list; | ||
53 | unsigned char macaddress_A[ETH_ALEN]; | ||
54 | unsigned char macaddress_B[ETH_ALEN]; | ||
55 | /* Local slave through which AddrB frames are received from this node */ | ||
56 | enum hsr_port_type addr_B_port; | ||
57 | unsigned long time_in[HSR_PT_PORTS]; | ||
58 | bool time_in_stale[HSR_PT_PORTS]; | ||
59 | u16 seq_out[HSR_PT_PORTS]; | ||
60 | struct rcu_head rcu_head; | ||
61 | }; | ||
62 | |||
51 | #endif /* __HSR_FRAMEREG_H */ | 63 | #endif /* __HSR_FRAMEREG_H */ |
diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h index 1e49675ca186..778213f07fe0 100644 --- a/net/hsr/hsr_main.h +++ b/net/hsr/hsr_main.h | |||
@@ -163,6 +163,10 @@ struct hsr_priv { | |||
163 | u8 prot_version; /* Indicate if HSRv0 or HSRv1. */ | 163 | u8 prot_version; /* Indicate if HSRv0 or HSRv1. */ |
164 | spinlock_t seqnr_lock; /* locking for sequence_nr */ | 164 | spinlock_t seqnr_lock; /* locking for sequence_nr */ |
165 | unsigned char sup_multicast_addr[ETH_ALEN]; | 165 | unsigned char sup_multicast_addr[ETH_ALEN]; |
166 | #ifdef CONFIG_DEBUG_FS | ||
167 | struct dentry *node_tbl_root; | ||
168 | struct dentry *node_tbl_file; | ||
169 | #endif | ||
166 | }; | 170 | }; |
167 | 171 | ||
168 | #define hsr_for_each_port(hsr, port) \ | 172 | #define hsr_for_each_port(hsr, port) \ |
@@ -179,4 +183,17 @@ static inline u16 hsr_get_skb_sequence_nr(struct sk_buff *skb) | |||
179 | return ntohs(hsr_ethhdr->hsr_tag.sequence_nr); | 183 | return ntohs(hsr_ethhdr->hsr_tag.sequence_nr); |
180 | } | 184 | } |
181 | 185 | ||
186 | #if IS_ENABLED(CONFIG_DEBUG_FS) | ||
187 | int hsr_prp_debugfs_init(struct hsr_priv *priv); | ||
188 | void hsr_prp_debugfs_term(struct hsr_priv *priv); | ||
189 | #else | ||
190 | static inline int hsr_prp_debugfs_init(struct hsr_priv *priv) | ||
191 | { | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static inline void hsr_prp_debugfs_term(struct hsr_priv *priv) | ||
196 | {} | ||
197 | #endif | ||
198 | |||
182 | #endif /* __HSR_PRIVATE_H */ | 199 | #endif /* __HSR_PRIVATE_H */ |
diff --git a/net/hsr/hsr_prp_debugfs.c b/net/hsr/hsr_prp_debugfs.c new file mode 100644 index 000000000000..b30e98734c61 --- /dev/null +++ b/net/hsr/hsr_prp_debugfs.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * hsr_prp_debugfs code | ||
3 | * Copyright (C) 2017 Texas Instruments Incorporated | ||
4 | * | ||
5 | * Author(s): | ||
6 | * Murali Karicheri <m-karicheri2@ti.com? | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation version 2. | ||
11 | * | ||
12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
13 | * kind, whether express or implied; without even the implied warranty | ||
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/debugfs.h> | ||
20 | #include "hsr_main.h" | ||
21 | #include "hsr_framereg.h" | ||
22 | |||
23 | static void print_mac_address(struct seq_file *sfp, unsigned char *mac) | ||
24 | { | ||
25 | seq_printf(sfp, "%02x:%02x:%02x:%02x:%02x:%02x:", | ||
26 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | ||
27 | } | ||
28 | |||
29 | /* hsr_prp_node_table_show - Formats and prints node_table entries */ | ||
30 | static int | ||
31 | hsr_prp_node_table_show(struct seq_file *sfp, void *data) | ||
32 | { | ||
33 | struct hsr_priv *priv = (struct hsr_priv *)sfp->private; | ||
34 | struct hsr_node *node; | ||
35 | |||
36 | seq_puts(sfp, "Node Table entries\n"); | ||
37 | seq_puts(sfp, "MAC-Address-A, MAC-Address-B, time_in[A], "); | ||
38 | seq_puts(sfp, "time_in[B], Address-B port\n"); | ||
39 | rcu_read_lock(); | ||
40 | list_for_each_entry_rcu(node, &priv->node_db, mac_list) { | ||
41 | /* skip self node */ | ||
42 | if (hsr_addr_is_self(priv, node->macaddress_A)) | ||
43 | continue; | ||
44 | print_mac_address(sfp, &node->macaddress_A[0]); | ||
45 | seq_puts(sfp, " "); | ||
46 | print_mac_address(sfp, &node->macaddress_B[0]); | ||
47 | seq_printf(sfp, "0x%lx, ", node->time_in[HSR_PT_SLAVE_A]); | ||
48 | seq_printf(sfp, "0x%lx ", node->time_in[HSR_PT_SLAVE_B]); | ||
49 | seq_printf(sfp, "0x%x\n", node->addr_B_port); | ||
50 | } | ||
51 | rcu_read_unlock(); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | /* hsr_prp_node_table_open - Open the node_table file | ||
56 | * | ||
57 | * Description: | ||
58 | * This routine opens a debugfs file node_table of specific hsr device | ||
59 | */ | ||
60 | static int | ||
61 | hsr_prp_node_table_open(struct inode *inode, struct file *filp) | ||
62 | { | ||
63 | return single_open(filp, hsr_prp_node_table_show, inode->i_private); | ||
64 | } | ||
65 | |||
66 | static const struct file_operations hsr_prp_fops = { | ||
67 | .owner = THIS_MODULE, | ||
68 | .open = hsr_prp_node_table_open, | ||
69 | .read = seq_read, | ||
70 | .llseek = seq_lseek, | ||
71 | .release = single_release, | ||
72 | }; | ||
73 | |||
74 | /* hsr_prp_debugfs_init - create hsr-prp node_table file for dumping | ||
75 | * the node table | ||
76 | * | ||
77 | * Description: | ||
78 | * When debugfs is configured this routine sets up the node_table file per | ||
79 | * hsr/prp device for dumping the node_table entries | ||
80 | */ | ||
81 | int hsr_prp_debugfs_init(struct hsr_priv *priv) | ||
82 | { | ||
83 | int rc = -1; | ||
84 | struct dentry *de = NULL; | ||
85 | |||
86 | de = debugfs_create_dir("hsr", NULL); | ||
87 | if (!de) { | ||
88 | pr_err("Cannot create hsr-prp debugfs root\n"); | ||
89 | return rc; | ||
90 | } | ||
91 | |||
92 | priv->node_tbl_root = de; | ||
93 | |||
94 | de = debugfs_create_file("node_table", S_IFREG | 0444, | ||
95 | priv->node_tbl_root, priv, | ||
96 | &hsr_prp_fops); | ||
97 | if (!de) { | ||
98 | pr_err("Cannot create hsr-prp node_table directory\n"); | ||
99 | return rc; | ||
100 | } | ||
101 | priv->node_tbl_file = de; | ||
102 | rc = 0; | ||
103 | |||
104 | return rc; | ||
105 | } | ||
106 | |||
107 | /* hsr_prp_debugfs_term - Tear down debugfs intrastructure | ||
108 | * | ||
109 | * Description: | ||
110 | * When Debufs is configured this routine removes debugfs file system | ||
111 | * elements that are specific to hsr-prp | ||
112 | */ | ||
113 | void | ||
114 | hsr_prp_debugfs_term(struct hsr_priv *priv) | ||
115 | { | ||
116 | debugfs_remove(priv->node_tbl_file); | ||
117 | priv->node_tbl_file = NULL; | ||
118 | debugfs_remove(priv->node_tbl_root); | ||
119 | priv->node_tbl_root = NULL; | ||
120 | } | ||