From: Jon M. <jon...@er...> - 2019-07-30 12:51:05
|
Acked-by: Jon Maloy <jon...@er...> I just have one minor comment. See below. And forget about what I said about "on the fly" device detection. Since we have to register a handler anyway that wouldn't improve anything. ///jon > -----Original Message----- > From: joh...@de... <joh...@de...> > Sent: 18-Jul-19 23:10 > To: tip...@li... > Subject: [tipc-discussion] [net-next v3] tipc: add loopback device tracking > > From: John Rutherford <joh...@de...> > > 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 <joh...@de...> > --- > net/tipc/bcast.c | 4 +++- > net/tipc/bearer.c | 65 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > net/tipc/bearer.h | 10 +++++++++ > net/tipc/core.c | 5 +++++ > net/tipc/core.h | 3 +++ > net/tipc/node.c | 1 + > net/tipc/topsrv.c | 2 ++ > 7 files changed, 89 insertions(+), 1 deletion(-) > > diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 6c997d4..235331d > 100644 > --- a/net/tipc/bcast.c > +++ b/net/tipc/bcast.c > @@ -406,8 +406,10 @@ int tipc_mcast_xmit(struct net *net, struct > sk_buff_head *pkts, > rc = tipc_bcast_xmit(net, pkts, cong_link_cnt); > } > > - if (dests->local) > + if (dests->local) { > + tipc_loopback_trace(net, &localq); > tipc_sk_mcast_rcv(net, &localq, &inputq); > + } > exit: > /* This queue should normally be empty by now */ > __skb_queue_purge(pkts); > diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 2bed658..5273ec5 > 100644 > --- a/net/tipc/bearer.c > +++ b/net/tipc/bearer.c > @@ -389,6 +389,12 @@ int tipc_enable_l2_media(struct net *net, struct > tipc_bearer *b, > dev_put(dev); > return -EINVAL; > } > + if (dev == net->loopback_dev) { > + dev_put(dev); > + pr_info("Bearer <%s>: loopback device not permitted\n", Or maybe: "Enabling <%s> not permitted\n", b->name); > + return -EINVAL; > + } > > /* Autoconfigure own node identity if needed */ > if (!tipc_own_id(net) && hwaddr_len <= NODE_ID_LEN) { @@ -674,6 > +680,65 @@ void tipc_bearer_stop(struct net *net) > } > } > > +void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts) > +{ > + struct net_device *dev = net->loopback_dev; > + struct sk_buff *skb, *_skb; > + int exp; > + > + skb_queue_walk(pkts, _skb) { > + skb = pskb_copy(_skb, GFP_ATOMIC); > + if (!skb) > + continue; > + > + exp = SKB_DATA_ALIGN(dev->hard_header_len - > skb_headroom(skb)); > + if (exp > 0 && pskb_expand_head(skb, exp, 0, GFP_ATOMIC)) { > + kfree_skb(skb); > + continue; > + } > + > + skb_reset_network_header(skb); > + dev_hard_header(skb, dev, ETH_P_TIPC, dev->dev_addr, > + dev->dev_addr, skb->len); > + skb->dev = dev; > + skb->pkt_type = PACKET_HOST; > + skb->ip_summed = CHECKSUM_UNNECESSARY; > + skb->protocol = eth_type_trans(skb, dev); > + netif_rx_ni(skb); > + } > +} > + > +static int tipc_loopback_rcv_pkt(struct sk_buff *skb, struct net_device *dev, > + struct packet_type *pt, struct net_device *od) { > + consume_skb(skb); > + return NET_RX_SUCCESS; > +} > + > +int tipc_attach_loopback(struct net *net) { > + struct net_device *dev = net->loopback_dev; > + struct tipc_net *tn = tipc_net(net); > + > + if (!dev) > + return -ENODEV; > + > + dev_hold(dev); > + tn->loopback_pt.dev = dev; > + tn->loopback_pt.type = htons(ETH_P_TIPC); > + tn->loopback_pt.func = tipc_loopback_rcv_pkt; > + dev_add_pack(&tn->loopback_pt); > + return 0; > +} > + > +void tipc_detach_loopback(struct net *net) { > + struct tipc_net *tn = tipc_net(net); > + > + dev_remove_pack(&tn->loopback_pt); > + dev_put(net->loopback_dev); > +} > + > /* Caller should hold rtnl_lock to protect the bearer */ static int > __tipc_nl_add_bearer(struct tipc_nl_msg *msg, > struct tipc_bearer *bearer, int nlflags) diff --git > a/net/tipc/bearer.h b/net/tipc/bearer.h index 7f4c569..ea0f3c4 100644 > --- a/net/tipc/bearer.h > +++ b/net/tipc/bearer.h > @@ -232,6 +232,16 @@ void tipc_bearer_xmit(struct net *net, u32 > bearer_id, > struct tipc_media_addr *dst); > void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id, > struct sk_buff_head *xmitq); > +void tipc_clone_to_loopback(struct net *net, struct sk_buff_head > +*pkts); int tipc_attach_loopback(struct net *net); void > +tipc_detach_loopback(struct net *net); > + > +static inline void tipc_loopback_trace(struct net *net, > + struct sk_buff_head *pkts) > +{ > + if (unlikely(dev_nit_active(net->loopback_dev))) > + tipc_clone_to_loopback(net, pkts); > +} > > /* check if device MTU is too low for tipc headers */ static inline bool > tipc_mtu_bad(struct net_device *dev, unsigned int reserve) diff --git > a/net/tipc/core.c b/net/tipc/core.c index c837072..23cb379 100644 > --- a/net/tipc/core.c > +++ b/net/tipc/core.c > @@ -82,6 +82,10 @@ static int __net_init tipc_init_net(struct net *net) > if (err) > goto out_bclink; > > + err = tipc_attach_loopback(net); > + if (err) > + goto out_bclink; > + > return 0; > > out_bclink: > @@ -94,6 +98,7 @@ static int __net_init tipc_init_net(struct net *net) > > static void __net_exit tipc_exit_net(struct net *net) { > + tipc_detach_loopback(net); > tipc_net_stop(net); > tipc_bcast_stop(net); > tipc_nametbl_stop(net); > diff --git a/net/tipc/core.h b/net/tipc/core.h index 7a68e1b..60d8295 100644 > --- a/net/tipc/core.h > +++ b/net/tipc/core.h > @@ -125,6 +125,9 @@ struct tipc_net { > > /* Cluster capabilities */ > u16 capabilities; > + > + /* Tracing of node internal messages */ > + struct packet_type loopback_pt; > }; > > static inline struct tipc_net *tipc_net(struct net *net) diff --git > a/net/tipc/node.c b/net/tipc/node.c index 550581d..16d251b 100644 > --- a/net/tipc/node.c > +++ b/net/tipc/node.c > @@ -1443,6 +1443,7 @@ int tipc_node_xmit(struct net *net, struct > sk_buff_head *list, > int rc; > > if (in_own_node(net, dnode)) { > + tipc_loopback_trace(net, list); > tipc_sk_rcv(net, list); > return 0; > } > diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c index f345662..e3a6ba1 > 100644 > --- a/net/tipc/topsrv.c > +++ b/net/tipc/topsrv.c > @@ -40,6 +40,7 @@ > #include "socket.h" > #include "addr.h" > #include "msg.h" > +#include "bearer.h" > #include <net/sock.h> > #include <linux/module.h> > > @@ -608,6 +609,7 @@ static void tipc_topsrv_kern_evt(struct net *net, > struct tipc_event *evt) > memcpy(msg_data(buf_msg(skb)), evt, sizeof(*evt)); > skb_queue_head_init(&evtq); > __skb_queue_tail(&evtq, skb); > + tipc_loopback_trace(net, &evtq); > tipc_sk_rcv(net, &evtq); > } > > -- > 2.11.0 > > > > _______________________________________________ > tipc-discussion mailing list > tip...@li... > https://lists.sourceforge.net/lists/listinfo/tipc-discussion |