Page MenuHomeFreeBSD

ypbind: IPv6 clean by adding version 3 of ypbind
Needs ReviewPublic

Authored by yanhaowang on Jun 6 2024, 5:08 PM.
Tags
None
Referenced Files
F106195600: D45515.diff
Thu, Dec 26, 11:35 PM
Unknown Object (File)
Wed, Dec 25, 11:27 PM
Unknown Object (File)
Wed, Dec 25, 4:22 PM
Unknown Object (File)
Nov 20 2024, 4:09 PM
Unknown Object (File)
Nov 19 2024, 6:17 AM
Unknown Object (File)
Nov 13 2024, 3:19 AM
Unknown Object (File)
Nov 10 2024, 4:21 PM
Unknown Object (File)
Oct 26 2024, 10:49 AM
Subscribers

Details

Reviewers
hrs
lwhsu
Summary

Version 2 of YP uses TS-RPC and supports only IPv4 addresses. I am updating version 2 to use TI-RPC and adding support for IPv4/IPv6 in version 3.

Compile

  1. cd /usr/src/include/rpcsvc/ && make all install // Header
  2. cd /usr/src/lib/libc/ && make all install // Linker, met error
yp_xdr.c:277:2: error: must use 'struct' tag to refer to type 'netbuf'
  277 |         netbuf **pp = &objp->ypbind_svcaddr;
      |         ^
      |         struct 
1 error generated.
*** Error code 1

Stop.
make: stopped in /usr/src/lib/libc
  1. cd /usr/src/usr.sbin/ypbind/ && make all install // ypbind (RPC client)

TI-RPC Changes

  1. I replaced svcudp_create and svctcp_create with getnetconfig, svc_tp_create, and svc_reg within a while loop. This change binds version 3 of ypbind on every netconfig and binds version 2 of ypbind specifically on IPv4 over UDP/TCP.
  1. I use rpcb_unset nstead of pmap_unset to unset any program before registering in the main and terminate functions. pmap_unset uses portmap to unset, while rpcb_unset uses rpcbind to unset the mapper.
  1. Replaced clntudp_bufcreate with clnt_dg_create. Added a timeout using clnt_control because clnt_dg_create lacks a timeout parameter.
  1. Replaced clntudp_create with clnt_create.
  1. Replaced clnt_broadcast with rpc_broadcast. clnt_broadcast only broadcasts to portmap, whereas rpc_broadcast broadcasts to both portmap and rpcbind.

Version 3 ypbind

  1. I have included some version 3 data structures in "yp.x".
    1. Use new _dom_binding. It is very similar to the old one, except for the address. Version 3 uses a new data structure, ypbind_binding_3, to represent addresses.
    2. Use ypbind_setdom_3 to replace ypbind_setdom. The difference is that version 3 uses the new ypbind_binding_3 structure.
    3. Use ypbind_resp_3 to replace ypbind_resp, with the main difference still being ypbind_binding_3.
  1. I have added version 3 functions like ypbindprog_3, ypbindproc_domain_3_yp, and ypbindproc_setdom_3_yp, following Sun's implementation. In their code, version 2 structures are converted to version 3 structures before calling version 3 functions.
  1. I also revised the "yp_ping.c" function to support struct sockaddr *.

I couldn't fully test it as my test environment does not have a YP server.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 58143
Build 55031: arc lint + arc unit

Event Timeline

This patch attempts to implement version 3 of YP from Sun (https://src.illumos.org/source/xref/illumos-gate/usr/src/cmd/ypcmd/yp_b_svc.c?r=2a8bcb4e#337) into FreeBSD. It is part of my Google Summer of Code 2024 project (https://wiki.freebsd.org/SummerOfCode2024Projects/IPv6SupportAndCleanupOfAddressFamilyDependencyInUserlandUtilities). I believe uploading the ongoing work for discussion with my mentor (Hiroki) is efficient. If this is not a good approach, please let me know, and I will cancel the patch immediately and seek another way to discuss it.

Version 2 of YP uses TS-RPC and supports only IPv4 addresses. I am revising version 2 to use TI-RPC and adding support for IPv4/6 in version 3.

TI-RPC

  1. In the main function, I use getnetconfig, svc_tp_create, and svc_reg within a while loop to replace the original functions svcudp_create and svctcp_create. I attempt to bind version 3 of ypbind on every netconfig and bind version 2 of ypbind only on IPv4 over UDP/TCP.
  1. Use clnt_dg_create to replace clntudp_bufcreate function. And use the clnt_control function to add a timeout.
  1. Use clnt_create function to replace clntudp_create.
  1. Use rpc_broadcast function to replace clnt_broadcast.

Version 3 ypbind

  1. I have included some version 3 data structures in "yp.x".
    1. Use new _dom_binding. It is very similar to the old one, except for the address. Version 3 uses a new data structure, ypbind_binding_3, to represent addresses.
    2. Use ypbind_setdom_3 to replace ypbind_setdom. The difference is that version 3 uses the new ypbind_binding_3 structure.
    3. Use ypbind_resp_3 to replace ypbind_resp, with the main difference still being ypbind_binding_3.

      This is problem 1 because I am not sure if I included the data structure correctly. For example, I am not sure why there are two members, rpcvers_t ypbind_hi_vers and rpcvers_t ypbind_lo_vers, in ypbind_binding_3. In Sun's code, they seem the same.
  1. I have added version 3 functions like ypbindprog_3, ypbindproc_domain_3_yp, and ypbindproc_setdom_3_yp, following Sun's implementation. In their code, version 2 structures are converted to version 3 structures before calling version 3 functions.
  1. I also revised the "yp_ping.c" function to support struct sockaddr *.

The code compiles and I have run it without any error messages. However, I couldn't fully test it as my test environment does not have a YP server.

  • Restore "ypset.c" which add accidentally
hrs requested changes to this revision.Jun 6 2024, 7:21 PM
hrs added inline comments.
usr.sbin/ypbind/yp_ping.c
218

See comments for L.313 in ypbind.c

usr.sbin/ypbind/ypbind.c
69

When you want to use struct sockaddr_storage, use #include <netdb.h>.

106

The reason why two members for the version number is that hi_vers means the highest version number the service accepts, and the lo_vers means the lowest. So if these two are the same, the ypbind service will accept the specified version only.

237–240

memcpy() for the size of (struct netbuf) is not enough if you want to copy the buffer contents (netbuf->buf).

259

For a pointer access, use (struct sockaddr *) instead of (struct sockaddr_storage *) because the sockaddr is already address-family-independent and the sockaddr_storage is usually required only when the struct size that can hold any address families matters.

273

If fromsin is in (struct sockaddr *), you will not need two type-castings here.

282

If getnameinfo() is used, simply checking "::1" or "127.0.0.1" might be enough without checking sa_family. The same appears in L.1082.

293–298

The port number should be obtained from fromsin using ((struct sockaddr_in *)fromsin)->sin_port or ((struct sockaddr_in6 *)fromsin)->sin6_port, depending on sa_family.

351

Move typedefs outside the function.

993

Same as L.313 in ypbind.c

This revision now requires changes to proceed.Jun 6 2024, 7:21 PM

I did not test the functionality yet, but I will give it a try with IPv4 and IPv6 configurations.

  • Move variable to "yp.x" file and fix variable name
  • Revise according the advice from Hiroki
yanhaowang added inline comments.
usr.sbin/ypbind/ypbind.c
237–240

I add a utility function copy_netbuf to handle the situation while need to memcpy for struct netbuf.

  • Use rpcb_unset instead of pmap_unset
yanhaowang edited the summary of this revision. (Show Details)
yanhaowang edited the summary of this revision. (Show Details)

Update "yp.x" type

  1. Use unsigned int instead of rpcvers_t.
  2. Remove struct netconfig in ypbind_binding_3 structure.

Also update Symbole.map to include three functions because while compile ypbind we will meet

ld: error: undefined symbol: xdr_ypbind_resp_3
>>> referenced by ypbind.c:0 (/usr/src/usr.sbin/ypbind/ypbind.c:0)
>>>               ypbind.o:(ypbindprog_3)

ld: error: undefined symbol: xdr_ypbind_domain_3
>>> referenced by ypbind.c:0 (/usr/src/usr.sbin/ypbind/ypbind.c:0)
>>>               ypbind.o:(ypbindprog_3)

ld: error: undefined symbol: xdr_ypbind_setdom_3
>>> referenced by ypbind.c:0 (/usr/src/usr.sbin/ypbind/ypbind.c:0)
>>>               ypbind.o:(ypbindprog_3
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1

Stop.
make: stopped in /usr/src/usr.sbin/ypbind

However while update /lib/libc/yp/Symbol.map, we would meet error while compile it in /lib/libc/ like below.

yp_xdr.c:277:2: error: must use 'struct' tag to refer to type 'netbuf'
  277 |         netbuf **pp = &objp->ypbind_svcaddr;
      |         ^
      |         struct 
1 error generated.
*** Error code 1

Stop.
make: stopped in /usr/src/lib/libc