Hi Alessio,

Don’t call adj_nbr_add_or_lock from a worker thread, it must only be called 
from the main thread – the adjacency DB is not thread safe. Stash the result of 
the call in your ‘key’ object.

/neale

From: Alessio Silvestro <ale.silver...@gmail.com>
Date: Friday, 14 July 2017 at 14:15
To: "Neale Ranns (nranns)" <nra...@cisco.com>
Cc: Dharmaray Kundargi <dharmaray.kunda...@mavenir.com>, "Klement Sekera -X 
(ksekera - PANTHEON TECHNOLOGIES at Cisco)" <ksek...@cisco.com>, 
"vpp-dev@lists.fd.io" <vpp-dev@lists.fd.io>
Subject: Re: [vpp-dev] VPP: Answer UDP Packets

[SOLVED]

the variable must be declared as ==> extern adj_index_t adj_index;

In my case, I have 3 workers configured. Now it works.

Cheers,
Alessio


On Thu, Jul 13, 2017 at 3:12 PM, Alessio Silvestro 
<ale.silver...@gmail.com<mailto:ale.silver...@gmail.com>> wrote:
Hi Neale,

thanks for the info.

I was already doing that, but I get an unpredictable behavior from vpp.

My node listens for UDP packets. For each packet, it creates a new packet and 
send it back to the source IP address.

Below the piece of code that set the buffer's parameters.

adj_index_t adj_index;
adj_index =  adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,VNET_LINK_IP4,
                                            (const 
ip46_address_t*)&key.peer_addr,
                                            key.sw_if_index);

b->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
vnet_buffer (b)->ip.adj_index[VLIB_RX] = adj_index;
vnet_buffer (b)->ip.adj_index[VLIB_TX]= adj_index;
vnet_buffer (b)->sw_if_index[VLIB_RX] = key.sw_if_index;
vnet_buffer (b)->sw_if_index[VLIB_TX] = key.sw_if_index;


where the key variable includes the IP addresses and sw_if_index taken from the 
source buffer.

Sometimes I am able to receive and send back UDP traffic. In those cases, the 
adj_index has value 1.

In the other cases, VPP crashes and I got the following error message:

1: /root/vpp/build-data/../src/vlib/node.c:102 (vlib_node_runtime_update) 
assertion `vlib_get_thread_index () == 0' fails

Below the backtrace on GDB.

(gdb) bt
#0  0x00007ffff5e3a428 in __GI_raise (sig=sig@entry=6) at 
../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007ffff5e3c02a in __GI_abort () at abort.c:89
#2  0x0000000000407cc2 in os_panic () at 
/root/vpp/build-data/../src/vpp/vnet/main.c:263
#3  0x00007ffff661f5f9 in debugger () at 
/root/vpp/build-data/../src/vppinfra/error.c:84
#4  0x00007ffff661fa01 in _clib_error (how_to_die=2, function_name=0x0, 
line_number=0,
    fmt=0x7ffff7982d98 "%s:%d (%s) assertion `%s' fails") at 
/root/vpp/build-data/../src/vppinfra/error.c:143
#5  0x00007ffff79147e2 in vlib_node_runtime_update (vm=0x7ffff7b9d400 
<vlib_global_main>, node_index=257,
    next_index=1) at /root/vpp/build-data/../src/vlib/node.c:102
#6  0x00007ffff7915468 in vlib_node_add_next_with_slot (vm=0x7ffff7b9d400 
<vlib_global_main>, node_index=257,
    next_node_index=336, slot=1) at /root/vpp/build-data/../src/vlib/node.c:187
#7  0x00007ffff74b221c in vlib_node_add_next (vm=0x7ffff7b9d400 
<vlib_global_main>, node=257, next_node=336)
    at /root/vpp/build-data/../src/vlib/node_funcs.h:1080
#8  0x00007ffff74b2df6 in vnet_rewrite_init (vnm=0x6f1100 <vnet_main>, 
sw_if_index=1, this_node=257, next_node=336,
    rw=0x7fffb5f4fe40) at /root/vpp/build-data/../src/vnet/adj/rewrite.c:108
#9  0x00007ffff7493391 in adj_nbr_add_or_lock (nh_proto=FIB_PROTOCOL_IP4, 
link_type=VNET_LINK_IP4,
    nh_addr=0x7fffb60b0ad6, sw_if_index=1) at 
/root/vpp/build-data/../src/vnet/adj/adj_nbr.c:233
#10 0x00007ffff71686c3 in add_udp4_transport (vm=0x7fffb5f0df94, 
b=0x7fff5fea8080, query_id=55949, client_port=1112,
    key=...) at /root/vpp/build-data/../src/vnet/alessio/server.c:73
#11 0x00007ffff7168ba3 in send_answer (vm=0x7fffb5f0df94, rt=0x7fffb6561554, 
query_id=55949, client_port=1112,
    key=...) at /root/vpp/build-data/../src/vnet/alessio/server.c:201
#12 0x00007ffff7168e0c in server_inline (vm=0x7fffb5f0df94, 
node=0x7fffb6561554, from_frame=0x7fffb5fad900)
    at /root/vpp/build-data/../src/vnet/alessio/server.c:287
#13 0x00007ffff7168e85 in server (vm=0x7fffb5f0df94, node=0x7fffb6561554, 
from_frame=0x7fffb5fad900)
    at /root/vpp/build-data/../src/vnet/alessio/server.c:316
#14 0x00007ffff78f5007 in dispatch_node (vm=0x7fffb5f0df94, 
node=0x7fffb6561554, type=VLIB_NODE_TYPE_INTERNAL,
    dispatch_state=VLIB_NODE_STATE_POLLING, frame=0x7fffb5fad900, 
last_time_stamp=277689848578863)
    at /root/vpp/build-data/../src/vlib/main.c:1016
#15 0x00007ffff78f55c0 in dispatch_pending_node (vm=0x7fffb5f0df94, 
pending_frame_index=4,
    last_time_stamp=277689848578863) at 
/root/vpp/build-data/../src/vlib/main.c:1166
#16 0x00007ffff78f763c in vlib_main_or_worker_loop (vm=0x7fffb5f0df94, 
is_main=0)
    at /root/vpp/build-data/../src/vlib/main.c:1625
#17 0x00007ffff78f7730 in vlib_worker_loop (vm=0x7fffb5f0df94) at 
/root/vpp/build-data/../src/vlib/main.c:1650
#18 0x00007ffff7940d94 in vlib_worker_thread_fn (arg=0x7fffb54b7480)
    at /root/vpp/build-data/../src/vlib/threads.c:1378
#19 0x00007ffff6642b7c in clib_calljmp () at 
/root/vpp/build-data/../src/vppinfra/longjmp.S:110
#20 0x00007fff68d9ed60 in ?? ()
#21 0x00007ffff793c304 in vlib_worker_thread_bootstrap_fn (arg=0x7fffb54b7480)
    at /root/vpp/build-data/../src/vlib/threads.c:464
Backtrace stopped: previous frame inner to this frame (corrupt stack?)


Am I doing something theoretically wrong or do you think there is an error 
within the code?

Thanks,
Alessio






On Wed, Jul 12, 2017 at 5:38 PM, Neale Ranns (nranns) 
<nra...@cisco.com<mailto:nra...@cisco.com>> wrote:

Hi Alessio,

I can even give you the API ;)

/**
* @brief
*  Add (and lock) a new or lock an existing neighbour adjacency
*
* @param nh_proto
*  The protocol for the next-hop address (v4 or v6)
*
* @param link_type
*  A description of the protocol of the packets that will forward
*  through this adj. On an ethernet interface this is the MAC header's
*  ether-type
*
* @param nh_addr
*  The address of the next-hop/peer to send the packet to
*
* @param sw_if_index
*  The interface on which the peer resides
*/
extern adj_index_t adj_nbr_add_or_lock(fib_protocol_t nh_proto,
                                                                       
vnet_link_t link_type,
                                                                       const 
ip46_address_t *nh_addr,
                                                                       u32 
sw_if_index);

/neale

From: Alessio Silvestro 
<ale.silver...@gmail.com<mailto:ale.silver...@gmail.com>>
Date: Wednesday, 12 July 2017 at 15:30
To: "Neale Ranns (nranns)" <nra...@cisco.com<mailto:nra...@cisco.com>>
Cc: Dharmaray Kundargi 
<dharmaray.kunda...@mavenir.com<mailto:dharmaray.kunda...@mavenir.com>>, 
"Klement Sekera -X (ksekera - PANTHEON TECHNOLOGIES at Cisco)" 
<ksek...@cisco.com<mailto:ksek...@cisco.com>>, 
"vpp-dev@lists.fd.io<mailto:vpp-dev@lists.fd.io>" 
<vpp-dev@lists.fd.io<mailto:vpp-dev@lists.fd.io>>

Subject: Re: [vpp-dev] VPP: Answer UDP Packets

Hi Neale,

can you please point me a code example of how to access the adjacency-DB in 
order to get the adjacency index to use for the ip4-rewrite node?

Thanks,
Alessio

On Wed, Jun 21, 2017 at 12:53 PM, Neale Ranns (nranns) 
<nra...@cisco.com<mailto:nra...@cisco.com>> wrote:
Hi Dharmaray,

The short answer is that ip4-lookup performs the lookup in a FIB table of the 
packet’s destination address, the result of which is an adjacency. The 
ip4-rewrite node applies the ‘L2’ encap of an adjacency and transmits the 
packet on the output port*. So typically packets will go first to ip4-lookup, 
get the adjacency, then proceed to ip4-rewrite.

When choosing between which of the two nodes to send your packet to, you should 
consider which of the pre-conditions for the required data you meet. In order 
to perform the IP lookup, the node needs to know which FIB table to use. In 
order to perform the rewrite, the node needs to know which adjacency to use.
So if you want to send your packet to the ip4-rewrite node, then you must have 
already chosen which adjacency to use. For single-hop BFD this is a simple 
matter of getting the adjacency from the adjacency-DB based on the peer and 
interface – you can think of this as caching the result of the lookup. The 
advantage of this is that we bypass the ip4-lookup node and so don’t pay its 
performance cost.

If you know the next-hop to send to, but not the interface (and so can’t use 
the adjacency-DB directly) then you can register with the FIB to track that 
next-hop and be informed of the changing adjacency to use.

Hth,
neale

*typically. The exception being tunnels.

-----Original Message-----
From: <vpp-dev-boun...@lists.fd.io<mailto:vpp-dev-boun...@lists.fd.io>> on 
behalf of Dharmaray Kundargi 
<dharmaray.kunda...@mavenir.com<mailto:dharmaray.kunda...@mavenir.com>>
Date: Wednesday, 21 June 2017 at 10:48
To: "Klement Sekera -X (ksekera - PANTHEON TECHNOLOGIES at Cisco)" 
<ksek...@cisco.com<mailto:ksek...@cisco.com>>, Alessio Silvestro 
<ale.silver...@gmail.com<mailto:ale.silver...@gmail.com>>
Cc: "vpp-dev@lists.fd.io<mailto:vpp-dev@lists.fd.io>" 
<vpp-dev@lists.fd.io<mailto:vpp-dev@lists.fd.io>>
Subject: Re: [vpp-dev] VPP: Answer UDP Packets

    BFD UDP code is interesting example.

    I was looking at bfd_udp_input rather and one question in relation to this.
    Though both ' bfd_udp_input ()' and ' bfd_send_periodic()' form the IP and 
UDP headers using ' bfd_add_transport_layer', they pass the packet to different 
next nodes.
    bfd_udp_input uses "ip4-lookup" as the next node whereas ' 
bfd_send_periodic()' uses "ip4-rewrite".

    So what's the difference between these two nodes? (ip4-rewrite vs ip4- 
lookup) and when to use what ?

    Regards
    Dharmaray




    -----Original Message-----
    From: vpp-dev-boun...@lists.fd.io<mailto:vpp-dev-boun...@lists.fd.io> 
[mailto:vpp-dev-boun...@lists.fd.io<mailto:vpp-dev-boun...@lists.fd.io>] On 
Behalf Of Klement Sekera -X (ksekera - PANTHEON TECHNOLOGIES at Cisco)
    Sent: Monday, June 19, 2017 12:09 PM
    To: Alessio Silvestro 
<ale.silver...@gmail.com<mailto:ale.silver...@gmail.com>>
    Cc: vpp-dev@lists.fd.io<mailto:vpp-dev@lists.fd.io>
    Subject: Re: [vpp-dev] VPP: Answer UDP Packets

    Couple of potential issues which I see:

    1.) if this buffer is generated by vpp, it should be flagged as such 
(b->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;)

    2.) I don't see it passed to another node - you need to create a frame and 
associate the buffer with it, then pass the frame to the next node, which would 
be either ip4-arp or ip4-rewrite for ipv4 case depending on whether the arp 
resolution has taken place or not...

    take a look at functions

    bfd_udp_init() - where the next nodes are resolved
    bfd_transport_udp4() - where the next node is decided and frame created

    You can take a look at show error and show trace to see what happens to the 
packet..

    HTH,
    Klement


    Quoting Alessio Silvestro (2017-06-16 17:20:30)
    >    Dear Klement,
    >
    >    thanks for the hint. I had a look at the code bfd_main.c and in 
particular
    >    at the function bfd_send_periodic().
    >
    >    I wrote the function send_udp_packet()  -- see below -- in order to 
send
    >    out UDP packets.
    >
    >    The function is executed (I can see from the VPP terminal) and no
    >    exception is raised, however I do not see any packet out.
    >
    >    1 -- is the function correct or I am missing something?
    >
    >    2 -- if it is not correct, how I can see where the problem is?
    >
    >    Thanks,
    >
    >    Alessio
    >
    >    static void send_udp_packet(vlib_main_t * vm, vlib_node_runtime_t * 
rt){
    >        u32 bi;
    >        vlib_buffer_alloc (vm, &bi, 1)
    >        vlib_buffer_t *b = vlib_get_buffer (vm, bi);
    >        ASSERT (b->current_data == 0);
    >        memset (vnet_buffer (b), 0, sizeof (*vnet_buffer (b)));
    >        VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
    >        add_udp4_transport (vm,b);
    >    }
    >
    >    int add_udp4_transport (vlib_main_t * vm, vlib_buffer_t * b)
    >    {
    >        vnet_buffer (b)->ip.adj_index[VLIB_RX] =  ~0;
    >        vnet_buffer (b)->ip.adj_index[VLIB_TX]=  ~0;
    >        vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
    >        vnet_buffer (b)->sw_if_index[VLIB_TX] = ~0;
    >        u8 *data;
    >        udp_header_t *udp;
    >        ip4_header_t *ip;
    >        data = vlib_buffer_get_current (b);
    >        udp = (udp_header_t *) (data - sizeof (udp_header_t));
    >        ip = (ip4_header_t *) ((u8 *) udp - sizeof (ip4_header_t));
    >        // Build packet header
    >        u32 src_address = 167772161; //[1]10.0.0.1  u32 version
    >        u32 dst_address = 167772162; // 10.0.0.2 u32 version
    >        ip->src_address.as_u32 = src_address;
    >        ip->dst_address.as_u32 = dst_address;
    >        ip->ip_version_and_header_length = 0x45;
    >        ip->ttl = 254;
    >        ip->protocol = IP_PROTOCOL_UDP; //0x45 == IP_PROTOCOL_UDP
    >        ip->length = clib_host_to_net_u16 (b->current_length + sizeof 
(*udp));
    >        ip->checksum = ip4_header_checksum (ip);
    >        udp->src_port = DNS_SERVER_PORT;
    >        udp->dst_port = DNS_DST_PORT;
    >        udp->length = clib_host_to_net_u16 (b->current_length);
    >        udp->checksum = 0;
    >        b->current_length = sizeof (*ip) + sizeof (*udp);
    >        return 1;
    >    }
    >
    >    On Wed, Jun 14, 2017 at 6:56 PM, Klement Sekera -X (ksekera - PANTHEON
    >    TECHNOLOGIES at Cisco) 
<[2]ksek...@cisco.com<mailto:ksek...@cisco.com>> wrote:
    >
    >      Hi Alessio,
    >
    >      you can take a look at BFD code which
    >
    >      a.) creates and sends its own UDP packets - bfd_main.c -
    >      bfd_send_periodic() creates, encapsulates (UDP) and sends a packet 
out
    >      b.) loops back packets received - bfd_udp.c -
    > bfd_udp_echo_input()
    >
    >      I'm not sure what's your use case, whether you are trying to reuse
    >      existing buffer, but one of these should fit it.
    >
    >      Regards,
    >      Klement
    >
    >      Quoting Alessio Silvestro (2017-06-14 17:22:14)
    >      >    Dear all,
    >      >    I implemented a new VPP node that receives UDP traffic using the
    >      following
    >      >    function:
    >      >
    >      >    udp_register_dst_port (vm, PORT, my_node.index , 1 /* is_ip4 
*/);
    >      >
    >      >    I am able to parse the packet and I would like to be able to 
send
    >      back an
    >      >    UDP packet.
    >      >
    >      >    Looking at the source code, the only function that seems fit my
    >      scope is
    >      >    the following (in ~/vpp/src/vnet/udp/udp.h)
    >      >
    >      >    ip_udp_encap_one (vlib_main_t * vm, vlib_buffer_t * b0, u8 * 
ec0,
    >      word
    >      >    ec_len,
    >      >
    >      >              u8 is_ip4)
    >      >
    >      >    Is that correct or there is another function for this purpose?
    >      >
    >      >    Thanks in advance for any help.
    >      >
    >      >    Best regards,
    >      >
    >      >    Alessio
    >
    > References
    >
    >    Visible links
    >    1. http://10.0.0.1/
    >    2. mailto:ksek...@cisco.com<mailto:ksek...@cisco.com>
    _______________________________________________
    vpp-dev mailing list
    vpp-dev@lists.fd.io<mailto:vpp-dev@lists.fd.io>
    https://lists.fd.io/mailman/listinfo/vpp-dev
    ________________________________
    Please Note: My email address is changing. Starting May 1st 2017 my email 
will solely be my Mavenir email 
firstname.lastn...@mavenir.com<mailto:firstname.lastn...@mavenir.com>. All 
other prior email accounts will become inactive. To ensure continuity, please 
send all emails to my Mavenir email ID which is currently active and available 
for use.


    This e-mail message may contain confidential or proprietary information of 
Mavenir Systems, Inc. or its affiliates and is intended solely for the use of 
the intended recipient(s). If you are not the intended recipient of this 
message, you are hereby notified that any review, use or distribution of this 
information is absolutely prohibited and we request that you delete all copies 
in your control and contact us by e-mailing to 
secur...@mavenir.com<mailto:secur...@mavenir.com>. Thank You. This message 
contains the views of its author and may not necessarily reflect the views of 
Mavenir Systems, Inc. or its affiliates, who employ systems to monitor email 
messages, but make no representation that such messages are authorized, secure, 
uncompromised, or free from computer viruses, malware, or other defects.
    _______________________________________________
    vpp-dev mailing list
    vpp-dev@lists.fd.io<mailto:vpp-dev@lists.fd.io>
    https://lists.fd.io/mailman/listinfo/vpp-dev



_______________________________________________
vpp-dev mailing list
vpp-dev@lists.fd.io
https://lists.fd.io/mailman/listinfo/vpp-dev
  • [vpp-dev] VPP... Alessio Silvestro
    • Re: [vpp... Klement Sekera -X (ksekera - PANTHEON TECHNOLOGIES at Cisco)
      • Re: ... Alessio Silvestro
        • ... Klement Sekera -X (ksekera - PANTHEON TECHNOLOGIES at Cisco)
          • ... Dharmaray Kundargi
            • ... Neale Ranns (nranns)
              • ... Alessio Silvestro
                • ... Neale Ranns (nranns)
                • ... Alessio Silvestro
                • ... Alessio Silvestro
                • ... Neale Ranns (nranns)

Reply via email to