Change in netlink.c unrelated to the commit //E
On Tue, 18 Jun 2019, 02:23 John Rutherford, <john.rutherf...@dektech.com.au> wrote: > Since node internal messages are passed directly to socket it is not > possible to observe this message exchange 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 turned on/off by enabling/disabling the loopback "bearer" > "eth:lo". > > Signed-off-by: John Rutherford <john.rutherf...@dektech.com.au> > --- > net/tipc/bcast.c | 4 +++- > net/tipc/bearer.c | 67 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > net/tipc/bearer.h | 3 +++ > net/tipc/core.c | 5 +++- > net/tipc/core.h | 12 ++++++++++ > net/tipc/netlink.c | 2 +- > net/tipc/node.c | 1 + > net/tipc/topsrv.c | 2 ++ > 8 files changed, 93 insertions(+), 3 deletions(-) > > 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..27b4fd7 100644 > --- a/net/tipc/bearer.c > +++ b/net/tipc/bearer.c > @@ -836,6 +836,12 @@ int __tipc_nl_bearer_disable(struct sk_buff *skb, > struct genl_info *info) > > name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); > > + if (!strcmp(name, "eth:lo")) { > + tipc_net(net)->loopback_trace = false; > + pr_info("Disabled packet tracing on loopback interface\n"); > + return 0; > + } > + > bearer = tipc_bearer_find(net, name); > if (!bearer) > return -EINVAL; > @@ -881,6 +887,12 @@ int __tipc_nl_bearer_enable(struct sk_buff *skb, > struct genl_info *info) > > bearer = nla_data(attrs[TIPC_NLA_BEARER_NAME]); > > + if (!strcmp(bearer, "eth:lo")) { > + tipc_net(net)->loopback_trace = true; > + pr_info("Enabled packet tracing on loopback interface\n"); > + return 0; > + } > + > if (attrs[TIPC_NLA_BEARER_DOMAIN]) > domain = nla_get_u32(attrs[TIPC_NLA_BEARER_DOMAIN]); > > @@ -1021,6 +1033,61 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct > genl_info *info) > return err; > } > > +void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *xmitq) > +{ > + struct net_device *dev = net->loopback_dev; > + struct sk_buff *skb, *_skb; > + int exp; > + > + skb_queue_walk(xmitq, _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); > + skb->dev = dev; > + skb->protocol = htons(ETH_P_TIPC); > + dev_hard_header(skb, dev, ETH_P_TIPC, dev->dev_addr, > + dev->dev_addr, skb->len); > + dev_queue_xmit(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; > + tn->loopback_trace = false; > + 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); > +} > + > static int __tipc_nl_add_media(struct tipc_nl_msg *msg, > struct tipc_media *media, int nlflags) > { > diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h > index 7f4c569..ef7fad9 100644 > --- a/net/tipc/bearer.h > +++ b/net/tipc/bearer.h > @@ -232,6 +232,9 @@ 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 *xmitq); > +int tipc_attach_loopback(struct net *net); > +void tipc_detach_loopback(struct net *net); > > /* 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 ed536c0..1867687 100644 > --- a/net/tipc/core.c > +++ b/net/tipc/core.c > @@ -81,7 +81,9 @@ static int __net_init tipc_init_net(struct net *net) > err = tipc_bcast_init(net); > if (err) > goto out_bclink; > - > + err = tipc_attach_loopback(net); > + if (err) > + goto out_bclink; > return 0; > > out_bclink: > @@ -94,6 +96,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..c1c2906 100644 > --- a/net/tipc/core.h > +++ b/net/tipc/core.h > @@ -67,6 +67,7 @@ struct tipc_link; > struct tipc_name_table; > struct tipc_topsrv; > struct tipc_monitor; > +void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts); > > #define TIPC_MOD_VER "2.0.0" > > @@ -125,6 +126,10 @@ struct tipc_net { > > /* Cluster capabilities */ > u16 capabilities; > + > + /* Tracing of node internal messages */ > + struct packet_type loopback_pt; > + bool loopback_trace; > }; > > static inline struct tipc_net *tipc_net(struct net *net) > @@ -152,6 +157,13 @@ static inline struct tipc_topsrv *tipc_topsrv(struct > net *net) > return tipc_net(net)->topsrv; > } > > +static inline void tipc_loopback_trace(struct net *net, > + struct sk_buff_head *pkts) > +{ > + if (unlikely(tipc_net(net)->loopback_trace)) > + tipc_clone_to_loopback(net, pkts); > +} > + > static inline unsigned int tipc_hashfn(u32 addr) > { > return addr & (NODE_HTABLE_SIZE - 1); > diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c > index 99bd166..d6165ad 100644 > --- a/net/tipc/netlink.c > +++ b/net/tipc/netlink.c > @@ -261,7 +261,7 @@ struct genl_family tipc_genl_family __ro_after_init = { > .version = TIPC_GENL_V2_VERSION, > .hdrsize = 0, > .maxattr = TIPC_NLA_MAX, > - .policy = tipc_nl_policy, > + .policy = tipc_nl_policy, > .netnsok = true, > .module = THIS_MODULE, > .ops = tipc_genl_v2_ops, > diff --git a/net/tipc/node.c b/net/tipc/node.c > index 9e106d3..7e58831 100644 > --- a/net/tipc/node.c > +++ b/net/tipc/node.c > @@ -1439,6 +1439,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 > tipc-discussion@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/tipc-discussion > _______________________________________________ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion