On 21 May 2015 at 17:45, Maxim Uvarov <maxim.uva...@linaro.org> wrote:

> From the rfc 3549 netlink looks like good protocol to communicate between
> data plane and control plane. And messages are defined by that protocol
> also. At least we should do something the same.
>
Netlink seems limited to the specific functionality already present in the
Linux kernel. An ODP IPC/message passing mechanism must be extensible and
support user-defined messages. There's no reason for ODP MBUS to impose any
message format.

Any (set of) applications can model their message formats on Netlink.

I don't understand how Netlink can be used to communicate between (any two)
two applications. Please enlighten me.

-- Ola


>
>
> Maxim.
>
> On 21 May 2015 at 17:46, Ola Liljedahl <ola.liljed...@linaro.org> wrote:
>
>> On 21 May 2015 at 15:56, Alexandru Badicioiu <
>> alexandru.badici...@linaro.org> wrote:
>>
>>> I got the impression that ODP MBUS API would define a transport
>>> protocol/API between an ODP
>>>
>> No the MBUS API is just an API for message passing (think of the OSE IPC
>> API) and doesn't specify use cases or content. Just like the ODP packet API
>> doesn't specify what the content in a packet means or the format of the
>> content.
>>
>>
>>> application and a control plane application, like TCP is the transport
>>> protocol for HTTP applications (e.g Web). Netlink defines exactly that -
>>> transport protocol for configuration messages.
>>> Maxim asked about the messages - should applications define the message
>>> format and/or the message content? Wouldn't be an easier task for the
>>> application to define only the content and let ODP to define a format?
>>>
>> How can you define a format when you don't know what the messages are
>> used for and what data needs to be transferred? Why should the MBUS API or
>> implementations care about the message format? It's just payload and none
>> of their business.
>>
>> If you want to, you can specify formats for specific purposes, e.g. reuse
>> Netlink formats for the functions that Netlink supports. Some ODP
>> applications may use this, other not (because they use some other protocol
>> or they implement some other functionality).
>>
>>
>>
>>> Reliability could be an issue but Netlink spec says how applications can
>>> create reliable protocols:
>>>
>>>
>>> One could create a reliable protocol between an FEC and a CPC by
>>>    using the combination of sequence numbers, ACKs, and retransmit
>>>    timers.  Both sequence numbers and ACKs are provided by Netlink;
>>>    timers are provided by Linux.
>>>
>>> And you could do the same in ODP but I prefer not to, this adds a level
>> of complexity to the application code I do not want. Perhaps the actual
>> MBUS implementation has to do this but then hidden from the applications.
>> Just like TCP reliability and ordering etc is hidden from the applications
>> that just do read and write.
>>
>>    One could create a heartbeat protocol between the FEC and CPC by
>>>    using the ECHO flags and the NLMSG_NOOP message.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On 21 May 2015 at 16:23, Ola Liljedahl <ola.liljed...@linaro.org> wrote:
>>>
>>>> On 21 May 2015 at 15:05, Alexandru Badicioiu <
>>>> alexandru.badici...@linaro.org> wrote:
>>>>
>>>>> I was referring to the  Netlink protocol in itself, as a model for ODP
>>>>> MBUS (or IPC).
>>>>>
>>>> Isn't the Netlink protocol what the endpoints send between them? This
>>>> is not specified by the ODP IPC/MBUS API, applications can define or re-use
>>>> whatever protocol they like. The protocol definition is heavily dependent
>>>> on what you actually use the IPC for and we shouldn't force ODP users to
>>>> use some specific predefined protocol.
>>>>
>>>> Also the "wire protocol" is left undefined, this is up to the
>>>> implementation to define and each platform can have its own definition.
>>>>
>>>> And netlink isn't even reliable. I know that that creates problems,
>>>> e.g. impossible to get a clean and complete snapshot of e.g. the routing
>>>> table.
>>>>
>>>>
>>>>> The interaction between the FEC and the CPC, in the Netlink context,
>>>>>    defines a protocol.  Netlink provides mechanisms for the CPC
>>>>>    (residing in user space) and the FEC (residing in kernel space) to
>>>>>    have their own protocol definition -- *kernel space and user space
>>>>>    just mean different protection domains*.  Therefore, a wire protocol
>>>>>    is needed to communicate.  The wire protocol is normally provided by
>>>>>    some privileged service that is able to copy between multiple
>>>>>    protection domains.  We will refer to this service as the Netlink
>>>>>    service.  The Netlink service can also be encapsulated in a different
>>>>>    transport layer, if the CPC executes on a different node than the
>>>>>    FEC.  The FEC and CPC, using Netlink mechanisms, may choose to define
>>>>>    a reliable protocol between each other.  By default, however, Netlink
>>>>>    provides an unreliable communication.
>>>>>
>>>>>    Note that the FEC and CPC can both live in the same memory protection
>>>>>    domain and use the connect() system call to create a path to the peer
>>>>>    and talk to each other.  We will not discuss this mechanism further
>>>>>    other than to say that it is available. Throughout this document, we
>>>>>    will refer interchangeably to the FEC to mean kernel space and the
>>>>>    CPC to mean user space.  This denomination is not meant, however, to
>>>>>    restrict the two components to these protection domains or to the
>>>>>    same compute node.
>>>>>
>>>>>
>>>>>
>>>>> On 21 May 2015 at 15:55, Ola Liljedahl <ola.liljed...@linaro.org>
>>>>> wrote:
>>>>>
>>>>>> On 21 May 2015 at 13:22, Alexandru Badicioiu <
>>>>>> alexandru.badici...@linaro.org> wrote:
>>>>>> > Hi,
>>>>>> > would Netlink protocol (https://tools.ietf.org/html/rfc3549) fit
>>>>>> the purpose
>>>>>> > of ODP IPC (within a single OS instance)?
>>>>>> I interpret this as a question whether Netlink would be fit as an
>>>>>> implementation of the ODP IPC (now called message bus because "IPC" is so
>>>>>> contended and imbued with different meanings).
>>>>>>
>>>>>> It is perhaps possible. Netlink seems a bit focused on intra-kernel
>>>>>> and kernel-to-user while the ODP IPC-MBUS is focused on user-to-user
>>>>>> (application-to-application).
>>>>>>
>>>>>> I see a couple of primary requirements:
>>>>>>
>>>>>>    - Support communication (message exchange) between user space
>>>>>>    processes.
>>>>>>    - Support arbitrary used-defined messages.
>>>>>>    - Ordered, reliable delivery of messages.
>>>>>>
>>>>>>
>>>>>> From the little I can quickly read up on Netlink, the first two
>>>>>> requirements do not seem supported. But perhaps someone with more 
>>>>>> intimate
>>>>>> knowledge of Netlink can prove me wrong. Or maybe Netlink can be extended
>>>>>> to support u2u and user-defined messages, the current specialization 
>>>>>> (e.g.
>>>>>> specialized addressing, specialized message formats) seems contrary to 
>>>>>> the
>>>>>> goals of providing generic mechanisms in the kernel that can be used for
>>>>>> different things.
>>>>>>
>>>>>> My IPC/MBUS reference implementation for linux-generic builds upon
>>>>>> POSIX message queues. One of my issues is that I want the message queue
>>>>>> associated with a process to go away when the process goes away. The
>>>>>> message queues are not independent entities.
>>>>>>
>>>>>> -- Ola
>>>>>>
>>>>>> >
>>>>>> > Thanks,
>>>>>> > Alex
>>>>>> >
>>>>>> > On 21 May 2015 at 14:12, Ola Liljedahl <ola.liljed...@linaro.org>
>>>>>> wrote:
>>>>>> >>
>>>>>> >> On 21 May 2015 at 11:50, Savolainen, Petri (Nokia - FI/Espoo)
>>>>>> >> <petri.savolai...@nokia.com> wrote:
>>>>>> >> >
>>>>>> >> >
>>>>>> >> >> -----Original Message-----
>>>>>> >> >> From: lng-odp [mailto:lng-odp-boun...@lists.linaro.org] On
>>>>>> Behalf Of
>>>>>> >> >> ext
>>>>>> >> >> Ola Liljedahl
>>>>>> >> >> Sent: Tuesday, May 19, 2015 1:04 AM
>>>>>> >> >> To: lng-odp@lists.linaro.org
>>>>>> >> >> Subject: [lng-odp] [RFC] Add ipc.h
>>>>>> >> >>
>>>>>> >> >> As promised, here is my first attempt at a standalone API for
>>>>>> IPC -
>>>>>> >> >> inter
>>>>>> >> >> process communication in a shared nothing architecture (message
>>>>>> passing
>>>>>> >> >> between processes which do not share memory).
>>>>>> >> >>
>>>>>> >> >> Currently all definitions are in the file ipc.h but it is
>>>>>> possible to
>>>>>> >> >> break out some message/event related definitions (everything
>>>>>> from
>>>>>> >> >> odp_ipc_sender) in a separate file message.h. This would mimic
>>>>>> the
>>>>>> >> >> packet_io.h/packet.h separation.
>>>>>> >> >>
>>>>>> >> >> The semantics of message passing is that sending a message to an
>>>>>> >> >> endpoint
>>>>>> >> >> will always look like it succeeds. The appearance of endpoints
>>>>>> is
>>>>>> >> >> explicitly
>>>>>> >> >> notified through user-defined messages specified in the
>>>>>> >> >> odp_ipc_resolve()
>>>>>> >> >> call. Similarly, the disappearance (e.g. death or otherwise lost
>>>>>> >> >> connection)
>>>>>> >> >> is also explicitly notified through user-defined messages
>>>>>> specified in
>>>>>> >> >> the
>>>>>> >> >> odp_ipc_monitor() call. The send call does not fail because the
>>>>>> >> >> addressed
>>>>>> >> >> endpoints has disappeared.
>>>>>> >> >>
>>>>>> >> >> Messages (from endpoint A to endpoint B) are delivered in
>>>>>> order. If
>>>>>> >> >> message
>>>>>> >> >> N sent to an endpoint is delivered, then all messages <N have
>>>>>> also been
>>>>>> >> >> delivered. Message delivery does not guarantee actual
>>>>>> processing by the
>>>>>> >> >
>>>>>> >> > Ordered is OK requirement, but "all messages <N have also been
>>>>>> >> > delivered" means in practice loss less delivery (== re-tries and
>>>>>> >> > retransmission windows, etc). Lossy vs loss less link should be
>>>>>> an
>>>>>> >> > configuration option.
>>>>>> >> I am just targeting internal communication which I expect to be
>>>>>> >> reliable. There is not any physical "link" involved. If an
>>>>>> >> implementation chooses to use some unreliable media, then it will
>>>>>> need
>>>>>> >> to take some counter measures. Any loss of message could be
>>>>>> detected
>>>>>> >> using sequence numbers (and timeouts) and handled by (temporary)
>>>>>> >> disconnection (so that no more messages will be delivered should
>>>>>> one
>>>>>> >> go missing).
>>>>>> >>
>>>>>> >> I am OK with adding the lossless/lossy configuration to the API as
>>>>>> >> long as lossless option is always implemented. Is this a
>>>>>> configuration
>>>>>> >> when creating the local  IPC endpoint or when sending a message to
>>>>>> >> another endpoint?
>>>>>> >>
>>>>>> >> >
>>>>>> >> > Also what "delivered" means?'
>>>>>> >> >
>>>>>> >> > Message:
>>>>>> >> >  - transmitted successfully over the link ?
>>>>>> >> >  - is now under control of the remote node (post office) ?
>>>>>> >> >  - delivered into application input queue ?
>>>>>> >> Probably this one but I am not sure the exact definition matters,
>>>>>> "has
>>>>>> >> been delivered" or "will eventually be delivered unless connection
>>>>>> to
>>>>>> >> the destination is lost". Maybe there is a better word than
>>>>>> >> "delivered?
>>>>>> >>
>>>>>> >> "Made available into the destination (recipient) address space"?
>>>>>> >>
>>>>>> >> >  - has been dequeued from application queue ?
>>>>>> >> >
>>>>>> >> >
>>>>>> >> >> recipient. End-to-end acknowledgements (using messages) should
>>>>>> be used
>>>>>> >> >> if
>>>>>> >> >> this guarantee is important to the user.
>>>>>> >> >>
>>>>>> >> >> IPC endpoints can be seen as interfaces (taps) to an internal
>>>>>> reliable
>>>>>> >> >> multidrop network where each endpoint has a unique address
>>>>>> which is
>>>>>> >> >> only
>>>>>> >> >> valid for the lifetime of the endpoint. I.e. if an endpoint is
>>>>>> >> >> destroyed
>>>>>> >> >> and then recreated (with the same name), the new endpoint will
>>>>>> have a
>>>>>> >> >> new address (eventually endpoints addresses will have to be
>>>>>> recycled
>>>>>> >> >> but
>>>>>> >> >> not for a very long time). Endpoints names do not necessarily
>>>>>> have to
>>>>>> >> >> be
>>>>>> >> >> unique.
>>>>>> >> >
>>>>>> >> > How widely these addresses are unique: inside one VM, multiple
>>>>>> VMs under
>>>>>> >> > the same host, multiple devices on a LAN (VLAN), ...
>>>>>> >> Currently, the scope of the name and address space is defined by
>>>>>> the
>>>>>> >> implementation. Perhaps we should define it? My current interest is
>>>>>> >> within an OS instance (bare metal or virtualised). Between
>>>>>> different
>>>>>> >> OS instances, I expect something based on IP to be used (because
>>>>>> you
>>>>>> >> don't know where those different OS/VM instances will be deployed
>>>>>> so
>>>>>> >> you need topology-independent addressing).
>>>>>> >>
>>>>>> >> Based on other feedback, I have dropped the contented usage of
>>>>>> "IPC"
>>>>>> >> and now call it "message bus" (MBUS).
>>>>>> >>
>>>>>> >> "MBUS endpoints can be seen as interfaces (taps) to an OS-internal
>>>>>> >> reliable multidrop network"...
>>>>>> >>
>>>>>> >> >
>>>>>> >> >
>>>>>> >> >>
>>>>>> >> >> Signed-off-by: Ola Liljedahl <ola.liljed...@linaro.org>
>>>>>> >> >> ---
>>>>>> >> >> (This document/code contribution attached is provided under the
>>>>>> terms
>>>>>> >> >> of
>>>>>> >> >> agreement LES-LTM-21309)
>>>>>> >> >>
>>>>>> >> >
>>>>>> >> >
>>>>>> >> >> +/**
>>>>>> >> >> + * Create IPC endpoint
>>>>>> >> >> + *
>>>>>> >> >> + * @param name Name of local IPC endpoint
>>>>>> >> >> + * @param pool Pool for incoming messages
>>>>>> >> >> + *
>>>>>> >> >> + * @return IPC handle on success
>>>>>> >> >> + * @retval ODP_IPC_INVALID on failure and errno set
>>>>>> >> >> + */
>>>>>> >> >> +odp_ipc_t odp_ipc_create(const char *name, odp_pool_t pool);
>>>>>> >> >
>>>>>> >> > This creates (implicitly) the local end point address.
>>>>>> >> >
>>>>>> >> >
>>>>>> >> >> +
>>>>>> >> >> +/**
>>>>>> >> >> + * Set the default input queue for an IPC endpoint
>>>>>> >> >> + *
>>>>>> >> >> + * @param ipc   IPC handle
>>>>>> >> >> + * @param queue Queue handle
>>>>>> >> >> + *
>>>>>> >> >> + * @retval  0 on success
>>>>>> >> >> + * @retval <0 on failure
>>>>>> >> >> + */
>>>>>> >> >> +int odp_ipc_inq_setdef(odp_ipc_t ipc, odp_queue_t queue);
>>>>>> >> >
>>>>>> >> > Multiple input queues are likely needed for different priority
>>>>>> messages.
>>>>>> >> >
>>>>>> >> >> +
>>>>>> >> >> +/**
>>>>>> >> >> + * Resolve endpoint by name
>>>>>> >> >> + *
>>>>>> >> >> + * Look up an existing or future endpoint by name.
>>>>>> >> >> + * When the endpoint exists, return the specified message with
>>>>>> the
>>>>>> >> >> endpoint
>>>>>> >> >> + * as the sender.
>>>>>> >> >> + *
>>>>>> >> >> + * @param ipc IPC handle
>>>>>> >> >> + * @param name Name to resolve
>>>>>> >> >> + * @param msg Message to return
>>>>>> >> >> + */
>>>>>> >> >> +void odp_ipc_resolve(odp_ipc_t ipc,
>>>>>> >> >> +                  const char *name,
>>>>>> >> >> +                  odp_ipc_msg_t msg);
>>>>>> >> >
>>>>>> >> > How widely these names are visible? Inside one VM, multiple VMs
>>>>>> under
>>>>>> >> > the same host, multiple devices on a LAN (VLAN), ...
>>>>>> >> >
>>>>>> >> > I think name service (or address resolution) are better handled
>>>>>> in
>>>>>> >> > middleware layer. If ODP provides unique addresses and message
>>>>>> passing
>>>>>> >> > mechanism, additional services can be built on top.
>>>>>> >> >
>>>>>> >> >
>>>>>> >> >> +
>>>>>> >> >> +/**
>>>>>> >> >> + * Monitor endpoint
>>>>>> >> >> + *
>>>>>> >> >> + * Monitor an existing (potentially already dead) endpoint.
>>>>>> >> >> + * When the endpoint is dead, return the specified message
>>>>>> with the
>>>>>> >> >> endpoint
>>>>>> >> >> + * as the sender.
>>>>>> >> >> + *
>>>>>> >> >> + * Unrecognized or invalid endpoint addresses are treated as
>>>>>> dead
>>>>>> >> >> endpoints.
>>>>>> >> >> + *
>>>>>> >> >> + * @param ipc IPC handle
>>>>>> >> >> + * @param addr Address of monitored endpoint
>>>>>> >> >> + * @param msg Message to return
>>>>>> >> >> + */
>>>>>> >> >> +void odp_ipc_monitor(odp_ipc_t ipc,
>>>>>> >> >> +                  const uint8_t addr[ODP_IPC_ADDR_SIZE],
>>>>>> >> >> +                  odp_ipc_msg_t msg);
>>>>>> >> >
>>>>>> >> > Again, I'd see node health monitoring and alarms as middleware
>>>>>> services.
>>>>>> >> >
>>>>>> >> >> +
>>>>>> >> >> +/**
>>>>>> >> >> + * Send message
>>>>>> >> >> + *
>>>>>> >> >> + * Send a message to an endpoint (which may already be dead).
>>>>>> >> >> + * Message delivery is ordered and reliable. All (accepted)
>>>>>> messages
>>>>>> >> >> will
>>>>>> >> >> be
>>>>>> >> >> + * delivered up to the point of endpoint death or lost
>>>>>> connection.
>>>>>> >> >> + * Actual reception and processing is not guaranteed (use
>>>>>> end-to-end
>>>>>> >> >> + * acknowledgements for that).
>>>>>> >> >> + * Monitor the remote endpoint to detect death or lost
>>>>>> connection.
>>>>>> >> >> + *
>>>>>> >> >> + * @param ipc IPC handle
>>>>>> >> >> + * @param msg Message to send
>>>>>> >> >> + * @param addr Address of remote endpoint
>>>>>> >> >> + *
>>>>>> >> >> + * @retval 0 on success
>>>>>> >> >> + * @retval <0 on error
>>>>>> >> >> + */
>>>>>> >> >> +int odp_ipc_send(odp_ipc_t ipc,
>>>>>> >> >> +              odp_ipc_msg_t msg,
>>>>>> >> >> +              const uint8_t addr[ODP_IPC_ADDR_SIZE]);
>>>>>> >> >
>>>>>> >> > This would be used to send a message to an address, but normal
>>>>>> >> > odp_queue_enq() could be used to circulate this event inside an
>>>>>> application
>>>>>> >> > (ODP instance).
>>>>>> >> >
>>>>>> >> >> +
>>>>>> >> >> +/**
>>>>>> >> >> + * Get address of sender (source) of message
>>>>>> >> >> + *
>>>>>> >> >> + * @param msg Message handle
>>>>>> >> >> + * @param addr Address of sender endpoint
>>>>>> >> >> + */
>>>>>> >> >> +void odp_ipc_sender(odp_ipc_msg_t msg,
>>>>>> >> >> +                 uint8_t addr[ODP_IPC_ADDR_SIZE]);
>>>>>> >> >> +
>>>>>> >> >> +/**
>>>>>> >> >> + * Message data pointer
>>>>>> >> >> + *
>>>>>> >> >> + * Return a pointer to the message data
>>>>>> >> >> + *
>>>>>> >> >> + * @param msg Message handle
>>>>>> >> >> + *
>>>>>> >> >> + * @return Pointer to the message data
>>>>>> >> >> + */
>>>>>> >> >> +void *odp_ipc_data(odp_ipc_msg_t msg);
>>>>>> >> >> +
>>>>>> >> >> +/**
>>>>>> >> >> + * Message data length
>>>>>> >> >> + *
>>>>>> >> >> + * Return length of the message data.
>>>>>> >> >> + *
>>>>>> >> >> + * @param msg Message handle
>>>>>> >> >> + *
>>>>>> >> >> + * @return Message length
>>>>>> >> >> + */
>>>>>> >> >> +uint32_t odp_ipc_length(const odp_ipc_msg_t msg);
>>>>>> >> >> +
>>>>>> >> >> +/**
>>>>>> >> >> + * Set message length
>>>>>> >> >> + *
>>>>>> >> >> + * Set length of the message data.
>>>>>> >> >> + *
>>>>>> >> >> + * @param msg Message handle
>>>>>> >> >> + * @param len New length
>>>>>> >> >> + *
>>>>>> >> >> + * @retval 0 on success
>>>>>> >> >> + * @retval <0 on error
>>>>>> >> >> + */
>>>>>> >> >> +int odp_ipc_reset(const odp_ipc_msg_t msg, uint32_t len);
>>>>>> >> >
>>>>>> >> > When data ptr or data len is modified: push/pull head, push/pull
>>>>>> tail
>>>>>> >> > would be analogies from packet API
>>>>>> >> >
>>>>>> >> >
>>>>>> >> > -Petri
>>>>>> >> >
>>>>>> >> >
>>>>>> >> _______________________________________________
>>>>>> >> lng-odp mailing list
>>>>>> >> lng-odp@lists.linaro.org
>>>>>> >> https://lists.linaro.org/mailman/listinfo/lng-odp
>>>>>> >
>>>>>> >
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> https://lists.linaro.org/mailman/listinfo/lng-odp
>>
>>
>
_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to