Skip to content

Commit 6c9081a

Browse files
johnr64davem330
authored andcommitted
tipc: add loopback device tracking
Since node internal messages are passed directly to the socket, it is not possible to observe those messages via tcpdump or wireshark. We now remedy this by making it possible to clone such messages and send the clones to the loopback interface. The clones are dropped at reception and have no functional role except making the traffic visible. The feature is enabled if network taps are active for the loopback device. pcap filtering restrictions require the messages to be presented to the receiving side of the loopback device. v3 - Function dev_nit_active used to check for network taps. - Procedure netif_rx_ni used to send cloned messages to loopback device. Signed-off-by: John Rutherford <[email protected]> Acked-by: Jon Maloy <[email protected]> Acked-by: Ying Xue <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2339ef1 commit 6c9081a

File tree

7 files changed

+88
-1
lines changed

7 files changed

+88
-1
lines changed

net/tipc/bcast.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,10 @@ int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
406406
rc = tipc_bcast_xmit(net, pkts, cong_link_cnt);
407407
}
408408

409-
if (dests->local)
409+
if (dests->local) {
410+
tipc_loopback_trace(net, &localq);
410411
tipc_sk_mcast_rcv(net, &localq, &inputq);
412+
}
411413
exit:
412414
/* This queue should normally be empty by now */
413415
__skb_queue_purge(pkts);

net/tipc/bearer.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,11 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
389389
dev_put(dev);
390390
return -EINVAL;
391391
}
392+
if (dev == net->loopback_dev) {
393+
dev_put(dev);
394+
pr_info("Enabling <%s> not permitted\n", b->name);
395+
return -EINVAL;
396+
}
392397

393398
/* Autoconfigure own node identity if needed */
394399
if (!tipc_own_id(net) && hwaddr_len <= NODE_ID_LEN) {
@@ -674,6 +679,65 @@ void tipc_bearer_stop(struct net *net)
674679
}
675680
}
676681

682+
void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts)
683+
{
684+
struct net_device *dev = net->loopback_dev;
685+
struct sk_buff *skb, *_skb;
686+
int exp;
687+
688+
skb_queue_walk(pkts, _skb) {
689+
skb = pskb_copy(_skb, GFP_ATOMIC);
690+
if (!skb)
691+
continue;
692+
693+
exp = SKB_DATA_ALIGN(dev->hard_header_len - skb_headroom(skb));
694+
if (exp > 0 && pskb_expand_head(skb, exp, 0, GFP_ATOMIC)) {
695+
kfree_skb(skb);
696+
continue;
697+
}
698+
699+
skb_reset_network_header(skb);
700+
dev_hard_header(skb, dev, ETH_P_TIPC, dev->dev_addr,
701+
dev->dev_addr, skb->len);
702+
skb->dev = dev;
703+
skb->pkt_type = PACKET_HOST;
704+
skb->ip_summed = CHECKSUM_UNNECESSARY;
705+
skb->protocol = eth_type_trans(skb, dev);
706+
netif_rx_ni(skb);
707+
}
708+
}
709+
710+
static int tipc_loopback_rcv_pkt(struct sk_buff *skb, struct net_device *dev,
711+
struct packet_type *pt, struct net_device *od)
712+
{
713+
consume_skb(skb);
714+
return NET_RX_SUCCESS;
715+
}
716+
717+
int tipc_attach_loopback(struct net *net)
718+
{
719+
struct net_device *dev = net->loopback_dev;
720+
struct tipc_net *tn = tipc_net(net);
721+
722+
if (!dev)
723+
return -ENODEV;
724+
725+
dev_hold(dev);
726+
tn->loopback_pt.dev = dev;
727+
tn->loopback_pt.type = htons(ETH_P_TIPC);
728+
tn->loopback_pt.func = tipc_loopback_rcv_pkt;
729+
dev_add_pack(&tn->loopback_pt);
730+
return 0;
731+
}
732+
733+
void tipc_detach_loopback(struct net *net)
734+
{
735+
struct tipc_net *tn = tipc_net(net);
736+
737+
dev_remove_pack(&tn->loopback_pt);
738+
dev_put(net->loopback_dev);
739+
}
740+
677741
/* Caller should hold rtnl_lock to protect the bearer */
678742
static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg,
679743
struct tipc_bearer *bearer, int nlflags)

net/tipc/bearer.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,16 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id,
232232
struct tipc_media_addr *dst);
233233
void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
234234
struct sk_buff_head *xmitq);
235+
void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts);
236+
int tipc_attach_loopback(struct net *net);
237+
void tipc_detach_loopback(struct net *net);
238+
239+
static inline void tipc_loopback_trace(struct net *net,
240+
struct sk_buff_head *pkts)
241+
{
242+
if (unlikely(dev_nit_active(net->loopback_dev)))
243+
tipc_clone_to_loopback(net, pkts);
244+
}
235245

236246
/* check if device MTU is too low for tipc headers */
237247
static inline bool tipc_mtu_bad(struct net_device *dev, unsigned int reserve)

net/tipc/core.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ static int __net_init tipc_init_net(struct net *net)
8282
if (err)
8383
goto out_bclink;
8484

85+
err = tipc_attach_loopback(net);
86+
if (err)
87+
goto out_bclink;
88+
8589
return 0;
8690

8791
out_bclink:
@@ -94,6 +98,7 @@ static int __net_init tipc_init_net(struct net *net)
9498

9599
static void __net_exit tipc_exit_net(struct net *net)
96100
{
101+
tipc_detach_loopback(net);
97102
tipc_net_stop(net);
98103
tipc_bcast_stop(net);
99104
tipc_nametbl_stop(net);

net/tipc/core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ struct tipc_net {
125125

126126
/* Cluster capabilities */
127127
u16 capabilities;
128+
129+
/* Tracing of node internal messages */
130+
struct packet_type loopback_pt;
128131
};
129132

130133
static inline struct tipc_net *tipc_net(struct net *net)

net/tipc/node.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,7 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
14431443
int rc;
14441444

14451445
if (in_own_node(net, dnode)) {
1446+
tipc_loopback_trace(net, list);
14461447
tipc_sk_rcv(net, list);
14471448
return 0;
14481449
}

net/tipc/topsrv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "socket.h"
4141
#include "addr.h"
4242
#include "msg.h"
43+
#include "bearer.h"
4344
#include <net/sock.h>
4445
#include <linux/module.h>
4546

@@ -608,6 +609,7 @@ static void tipc_topsrv_kern_evt(struct net *net, struct tipc_event *evt)
608609
memcpy(msg_data(buf_msg(skb)), evt, sizeof(*evt));
609610
skb_queue_head_init(&evtq);
610611
__skb_queue_tail(&evtq, skb);
612+
tipc_loopback_trace(net, &evtq);
611613
tipc_sk_rcv(net, &evtq);
612614
}
613615

0 commit comments

Comments
 (0)