From: Erik H. <eri...@er...> - 2015-02-06 11:52:51
|
On Mon, Jan 19, 2015 at 06:38:56PM +0800, Ying Xue wrote: > > I'm wondering if this would be feasible: > > 1. export the udp_send_skb() function > > 2. skb_push(sizeof udphdr) on the TIPC SKB. > > 3. Do a routing lookup for the destination ip and pass that, together with the > > TIPC SKB to udp_send_skb() > > > > It sounds like this is a hack method. Instead, we can understand how > these tunnels deal with our encountered issue as long as we look through > the tunnel interfaces implemented in networking with UDP socket. For > example, if we take a closer look at VXLAN code, we will find a better > approach to solve our issue. Actually VXLAN uses udp_tunnel to overcome > the difficulty: > > 1. Create UDP socket: > > vxlan_create_sock() > udp_sock_create() > > 2. Deliver SKB: > > vxlan_xmit_one() > vxlan_xmit_skb() > udp_tunnel_xmit_skb() > > In the entire sending path, no SKB copy happens. Moreover, when we use > the interfaces provided by udp_tunnel, both IPV4 and IPv6 are supported :) > > It seems that this is a perfect solution for us :) > > Maybe my analysis is not completely right as I just look through the > code of VXLAN. If I am wrong, please correct me :) Thanks for the tip! I replaced all deferred sending with something like this: clone = skb_clone(skb, GFP_ATOMIC); /*Routing lookup*/ memset(&fl, 0, sizeof(fl)); fl.daddr = dst->sin_addr.s_addr; fl.saddr = src->sin_addr.s_addr; fl.flowi4_mark = clone->mark; fl.flowi4_proto = IPPROTO_UDP; rt = ip_route_output_key(net, &fl); if (IS_ERR(rt)) { err = PTR_ERR(rt); pr_err("routing lookup failed\n"); } df = htons(IP_DF); clone->ignore_df = 0; skb_set_inner_protocol(clone, htons(ETH_P_TIPC)); sent = udp_tunnel_xmit_skb(ub->transmit, rt, clone, src->sin_addr.s_addr, dst->sin_addr.s_addr, 0, 255, df, src->sin_port, dst->sin_port, false); Works perfectly :) (i had to expand the BUF_HEADROM for tipc messages to have enough headroom for an IP+UDP header) //E |