? 2008?11?13? 22:33, James Carlson ??:
> Huafeng Lu writes:
>> To support the IP instance information, and to support future changes, 
>> we could change the API to use a TLV (type, length, value). We can put 
>> all paramters in a structure like:
>>      typedef cl_hook_param {
>>              int     cl_type;
>>              size_t  cl_len;
>>              uint8_t cl_value[];
>>      } cl_hook_param_t;
>> Thus, all future changes can be handled.
> 
> Not sure how that'd work, but I suggest discussing the issue with the
> other folks involved in the project and then bringing the completed
> proposal back for ARC review.
> 
> (My guess is that the 'types' defined effectively become part of the
> API itself, so the support for future changes given by that may be a
> little limited.)

Let me state it more clearly. The whole idea is illustrated below. We 
first define the following:

        typedef struct cl_hook_param {
                int     cl_type;
                uint8_t cl_value[];
        } cl_hook_param_t;

        int (*cl_inet_connect2)(cl_hook_param_t *chp);

        typedef struct cl_hook_conn_param {
                int             type;
                netstackid_t    stack_id;
                uint8_t         protocol;
                boolean_t       is_outgoing;
                sa_family_t     family;
                uint8_t         *laddrp;
                in_port_t       lport;
                uint8_t         *faddrp;
                in_port_t       fport;
        } cl_hook_conn_param_t;

To call the hook, at Solaris side, we do:

        cl_hook_conn_param_t hp;

        hp.type = CL_HOOK_TYPE_CONN;
        hp.stack_id = id;
        hp.protocol = IPPROTO_TCP;
        ...

        if ((err = cl_inet_connect2(&hp)) != 0)
                ...

At Cluster side, the hook implementation looks like:

        int cl_inet_connect_impl(cl_hook_param_t *chp)
        {
                if (chp->cl_type == CL_HOOK_TYPE_CONN) {
                        //get all arguments from chp->cl_value
                }
                ...
        }

In the future, if we want to add or change some arguments, we only need 
to change cl_hook_conn_param_t, while the hook signature will remain 
unchanged.


One issue with this approach is that, all existing Solaris that calls 
the hook need big code change - each needs to switch to the 
cl_hook_xxx_param_t structure. An alternative is to keep all existing 
arguments and the netstackid_t outside cl_hook_xxx_param_t, so that this 
time all the hook only need to add a "NULL" argument.

Signature:
        int (*cl_inet_connect2)(netstackid_t stack_id,
            uint8_t protocol, boolean_t is_outgoing,
            sa_family_t addr_family,
            uint8_t *laddrp, in_port_t lport,
            uint8_t *faddrp, in_port_t fport,
            cl_hook_param_t *chp) = NULL;

How to call it for now (the last argument is NULL):
        err = (*cl_inet_connect2)(id, IPPROTO_TCP, ..., fport, NULL);

In the future, when something changes, they can be put into 
cl_hook_xxx_param_t and passed into the hook.



How do you think?
--
Huafeng

Reply via email to