Original webrev
General
| Reviewer/ID | Comment | Disposition | Status |
|---|---|---|---|
| meem-001 | A number of functions are named without appropriate prefixes (e.g. nwam_) in ways that encroach upon actively evolved public namespaces. For instance, door_switch() and and dlpi_notify(). | ACCEPT | done |
| meem-002 | A number of functions use chumminess with lint to make arguments appear to be used (e.g., `foo = foo'). This is not a robust or clear way to handle unused arguments; please use ARGSUSED or the NOTE() facility to mark unused arguments. | ACCEPT | done |
| meem-003 | A number of places seem to check for pthread_mutex_lock() failure. This is needless: there are no cases short of programmer error that will lead to pthread_mutex_lock() failing (for a normal pthread lock). | ACCEPT | done |
| paul-01 | s/IPSec/IPsec/ | mph ACCEPT | done |
| sowmini-02 | why is netcfgd under $SRC/cmd/cmd-inet/lib/netcfgd? Seems like this is parallel to dlmgmtd for layer 3, so to be symmetric with dlmgtd, shouldn't it be under $SRC/cmd/netcfgd/*? at the very least, it would make sense to have $SRC/cmd/cmd-inet/nwam/netcfgd and $SRC/cmd/cmd-inet/nwam/nwamd ($SRC/cmd/cmd-inet/lib is misleading, since I don't think these apps get installed in /lib), but I think the cleaner solution is
$SRC/cmd/nwam/netcfgd
$SRC/cmd/nwam/nwamd
$SRC/cmd/nwam/common /* for common themes like daemonize() */
|
DISCUSS (thread) | done |
Packaging/RBAC
| Reviewer/ID | Comment | Disposition | Status |
|---|---|---|---|
| DJM-01 | user_attr: why aren't dladm,netadm,netcfg marked as roles ? Users shouldn't login to them directly right (yes I know they have locked accounts) | DISCUSS (thread) | done |
| DJM-02 | SUNWcrnet/postinstall: how is this going to be done in an IPS world ? | REJECT (thread) | done |
| DJM-03 | i.passwd: the change for dladm's group doesn't look like it will work for upgrade, see how I did the home dir change for the gdm user. | ACCEPT | done |
| paul-05/06 | exec_attr.txt: So, you have nwamadm and nwamcfg as part of the "Network Management" profile. But "Network IPsec Management" is part of "Network Security" and "IP Filter Management" appears to be in its own bucket (which is a pre-existing bug IMO, it should be in Network Security). It is not part of "Network Management", possibly on purpose. Anyway, nwamcfg and nwamadm implicitly give you the ability to manage IPfilter and IPsec policies if you have the solaris.network.autoconf.write authorization since you can define a property to override security policy. In fact, you must supply a property or policy gets blanked out IIRC. This is leaking the separation of privileges. What is the intention here as far as the privilege and authorization model? I'm not sure what the right balance is for your project and the previous requirements that caused this separation in the first place. | DISCUSS (thread) | done |
| paul-07 | user_attr.txt: Does netadm need the IPfilter service listed? | DISCUSS (thread) | done |
| tony-14 | Can changes in SUNWcnetr/postinstall be avoided? That is the mechanism should not rely on postinstall script since that wouldn't work with OpenSolaris. | DUP (DJM-02) | done |
| sowmini-01 | what is the difference between the netadm and netcfg uids? The Brussels II project is considering setting up /sbin/ipadm as owned by some dladm-like uid, and we had assumed this would be netadm. Should it be netcfg? | DISCUSS (thread) | done |
libinetcfg
| Reviewer/ID | Comment | Disposition | Status |
|---|---|---|---|
| seb-01 | inetcfg.c'General: I find it strange that an icfg_handle_t can either represent an IP interface or an IP address (i.e.: "logical interface"). It gives many of the new functions introduced have dual-functionality. For example, icfg_unplumb() is actually the same as icfg_remove_ipaddr() if the handle happens to be a "logical" interface. I would think that the model would be simpler if a handle were to strictly refer to an IP interface. You could have a different handle type for IP addresses if necessary. | ||
| seb-02 | inetcfg.c'General: Why not simplify ifconfig.c by having it use the new functions? | ||
| seb-03 | inetcfg.c'84: The user probably won't know what "Invalid DLPI link" means. Most don't know what DLPI is, as it's an API, and not something that exists at the administrative level. It would make more sense to me to have the DLPI_ENOLINK libdlpi error map to something that prints "link does not exist" or something similarly tangible. | ||
| seb-04 | inetcfg.c'86-90: These error strings are also quite implementation-specific, but since there's absolutely nothing that the admin can do about them, then it's probably not worth making them more friendly (unless you can think of something better). | ||
| seb-05 | inetcfg.c'92: I find it simpler without a count, and instead have a NULL-terminated array (e.g.: a last entry with a NULL error_desc). | ||
| seb-06 | inetcfg.c'116: You've just lost the actual error here. When DL_SYSERR is returned, errno indicates the actual system error code (see dlpi_strerror(3DLPI)). It would be good to indicate that error instead of a cryptic "DLPI error". For example, if it was ENOMEM, then you at least have a chance to print something meaningful given that you already have ICFG_NO_MEMORY. | ||
| seb-07 | inetcfg.c'2068: The addrlen argument is effectively not used; it should be removed. | ||
| seb-08 | inetcfg.c'2076,2079: You should verify sa_family == icfg_if_protocol()here. | ||
| seb-09 | inetcfg.c'2101 and almost every other place where errno gets set: ICFG_FAILURE ends up printing "Generic failure", which is not useful given that an actual specific error occured that was stored in errno. A function that translates errno's to ICFG_* errors would make this facility better. You'll need something like that anyway to address my previous concern regarding the mishandling of DL_SYSERR. | ||
| seb-10 | inetcfg.c'2171: This restriction seems unwarranted. Moreover, the condition it checks for can change immediately after the check, so even if it were intentional, it's not effective. | ||
| seb-11 | inetcfg.c'2193,2214,2270,2487: These duplicate code in ifconfig.c. ifconfig.c should be made to call these functions instead of maintaining two versions of the same code. | ||
| seb-12 | inetcfg.c'2270: There is no longer a plumb_one_device() in ifconfig.c, it's now ifplumb(). | ||
| seb-13 | inetcfg.c'2282: Remove spurious blank line. The indentation below also doesn't match above. | ||
| seb-14 | inetcfg.c'2290: An interface with the given name could be plumbed immediately after the check, so it doesn't add much value. Doesn't SIOCSLIFNAME already fail with an appropriate error code if the interface already exists anyway? | ||
| seb-15 | inetcfg.c'2347: What is "name string" referring to here? | ||
| seb-16 | inetcfg.c'2358,2535: Use strlcpy(). strncpy() can lead to subtle bugs since it doesn't guarantee that the result is NULL-terminated. | ||
| seb-17 | inetcfg.c'2499: Remove spurious blank line. | ||
| seb-18 | inetcfg.c'2501: Need blank line between variable declarations and code. | ||
| sowmini-10 | libinetcfg/Makefile: not sure I understand why this is necessary? According to $SRC/lib/README.Makefiles, after you define HDRS and HDRDIR, you one need check: $(CHECKHDRS) Could you explain why this is needed? | ||
| sowmini-11 | inetcfg.c'icfg_get_linkinfo is a dead function - can be removed | ||
| sowmini-12 | inetcfg.c: Not your introduction, but icfg_get_flags(), icfg_get_metric(), icfg_get_mtu(), icfg_get_index() should bzero the lifr as a first step. Also, these are exported functions that could be called with a NULL second argument, so they should verify that the flags/metric/etc. is not null before trying to set them. | ||
| sowmini-13 | inetcfg.c'1854: list == NULL, can happen if there are no links available, so I think this should only return ICFG_NO_MEMORY if lwp->lw_err = ENOMEM. also it may be that we ran out of memory half way through the walk, so we may still need to free memory. i.e., we shoudl goto done, and do
for (i = 0; i < lwp->lw_num; i++) {
free(..);
}
|
||
| sowmini-14 | inetcfg.c'1863: why only AF_INET? | ||
| sowmini-15 | inetcfg.c'icfg_plumb(): does this need to verify zone_check_datalink()? (ifconfig does this in inetplumb before calling ifplumb) | ||
| sowmini-16 | inetcfg.c'2333-2334: comments are incorrect - after the fix for CR6243060, the kernel only allows modifications to IFF_IPv4, IFF_IPV6, IFF_BROADCAST, IFF_XRESOLV. Thus you could skip lines 2339-2345, and instead start with lifr_flags of 0, before doing lines 2348-2354. | ||
| sowmini-17 | inetcfg.c'2368-2374: call icfg_get_flags instead of inlining this code. | ||
| sowmini-18 | inetcfg.c: is it necessary to expose errors like ICFG_NO_UNPLUMB_ARP/ICFG_NO_PLUMB_IP etc? How is the caller supposed to make sense of these errors? i.e., collapse lines 86-90 to two errors, ICFG_IF_CREATE_ERR and ICFG_IF_DESTROY_ERR (or some such pair of error codes) | ||
| sowmini-19 | inetcfg.c: Question: it looks like we need separate icfg_handle structures for IPv4 and IPv6 interfaces with nwamd_plumb_unplumb_interface being passed an af to plumb. How is the af determined (seems like the nwamd_ncu_state_machine figures this out. Also, I would have expected the code to do something like
icfg_open()
plumb interface
add addresses
... other stuff with the interface..
and maybe only do the icfg_close when the interface is unplumbed (but even that would result in needless creation of the ifh_sock), but I see an icfg_open/icfg_close pair for each operation like icfg_plumb, icfg_add_ipaddr etc. which would give rise to 6745288-like problems? Ideally we should have a single handle for ipv4 and ipv6 (with ifh_sock4, ifh_sock6), and then use the address itself to figure out which af was targetted (as needed). If that's not possible (because there are a lot of functions like icfg_set_mtu/icfg_set_metric which, though they are dead code with questionable semantics, are not getting cleaned up by this proposal) we should be restricting nwam usage of icfg_open to retain handle(s) for as long as possible, instead of doing an open/close per operation. |
||
| sowmini-20 | inetcfg.c'icfg_unplumb: if called with an ipmp interface, do we want to bail? (you would notice IFF_IPMP at line 2541) | ||
| sowmini-21 | inetcfg.c: If the PUNLINK of the arp stream fails at
2570 } else {
2571 ret = ICFG_NO_UNPLUMB_ARP;
2572 goto done;
2573 }
the code bails out and doesn't try to unplumb the IP stream, whereas onnv seems to- was this difference intentional? |
||
| sowmini-22 | libinetcfg/common/mapfile-vers: see coments for inetcfg.h - looks like only icfg_plumb, icfg_remove_ipaddr amd icfg_unplumb need to be added. | ||
| sowmini-23 | inetcfg.h: icfg_is_logical is not exported, so it can be made static to inetcfg.c. Similarly icfg_is_loopback, icfg_if_protocol. | ||
| sowmini-24 | llib-linetcfg: no changes to this file? |
nwamd (Michael Hunter)
| Reviewer/ID | Comment | Status |
|---|---|---|
| meem-094 | nwamd/dlpi_events.c'Throughout: libdlpi does not use `errno' for errors. All of the dlpi-related log messages in this file are busted. | done |
| meem-095 | nwamd/dlpi_events.c'34: Unclear what net/route.h has to do with this file. | done |
| meem-096 | nwamd/dlpi_events.c'65: This `if' clause is needless: nwamd has requested to only receive events of these two types. | done |
| meem-097 | nwamd/dlpi_events.c'67: Use of 'IFF_UP' to have some relationship to the link state seems wrong. Seems like it would be simpler to change link_state.link_state to link_state.link_up and just have it be a boolean. | BUG |
| meem-098 | nwamd/dlpi_events.c'71: Shouldn't this message explain the administrative impact? | done |
| meem-099 | nwamd/dlpi_events.c'88-102: Unclear why this function is allocating a buffer to receive into since it does nothing with this buffer – and even more unclear why this buffer is sized to DLPI_PHYSADDR_MAX. Seems like this whole function should just be:
static void *
nwamd_dlpi_thread(void *arg)
{
int rc;
dlpi_handle_t *dh = arg;
for (;;) {
rc = dlpi_recv(*dh, NULL, NULL, NULL, NULL, -1, NULL);
if (rc != DLPI_SUCCESS) {
nlog(LOG_ERR, "nwam_dlpi_thread: dlpi_recv "
"failed: %s", dlpi_strerror(rc));
break;
}
}
return (NULL);
}
|
done |
| meem-100 | nwamd/dlpi_events.c'94: Bogus cast. | done |
| meem-101 | nwamd/dlpi_events.c'99: Unclear where the magic notion of three failures comes from; one would think any unexpected failure would be worth stopping for. | done |
| meem-102 | nwamd/dlpi_events.c'100: presumably *dh was meant? | bug |
| meem-103 | nwamd/dlpi_events.c'105: This function would be much easier to read if a local variable was declared for ncu->ncu_node.u_link. | done |
| meem-104 | nwamd/dlpi_events.c'123: Can this happen? If so, what prevents a situation where two thread simultaneously pass this check and race to both call pthread_create()? | BUG |
| meem-105 | nwamd/dlpi_events.c'135, 182: Comments only tell me what is clear already from the code. | done |
| meem-106 | nwamd/dlpi_events.c'136-146: dlpi_bind() is no longer needed to use dlpi_enabnotify(). | done |
| meem-107 | nwamd/dlpi_events.c'150: Sure seems like `strdup(name)' ends up getting leaked here. Shouldn't this be NULL? | done |
| meem-108 | nwamd/dlpi_events.c'160: Presumably the intent is to record the error value returned from pthread_create() in the nlog() message? | done |
| seb-019 | How about moving nwamd out of usr/src/cmd/cmd-inet/... and up to usr/src/cmd? | Renee |
| seb-020 | README: This file is a very nice touch. More subsystems need this kind of documentation for developers. | done |
| seb-021 | README: Is there room for an nwam dtrace provider that can help track the various states of the objects maintained by nwamd to help with debugging? The strategy for debugging problems could include "give me the output of this dtrace script" instead of (or maybe in addition to) the current "set the debug SMF property, enable debugging in syslog, and give me the output of the syslog file". | EXPLAIN |
| seb-022 | README'124: It would help to expand the NCP, NCU, and ENM acronyms at least once in the README. | done |
| seb-023 | Makefile: For a daemon as central and critical to the system's operation as nwamd, it should be compiled with CTF data so that it can be debugged with dtrace and mdb. See the in.mpathd Makefile for an example of how to do this. | done |
| seb-024 | objects.h'45-52: There are over 90 other declarations of "object_name" in ON. Please use nwam-specific prefixes in nwam data structures to help with navigation of the code. | done |
| seb-025 | objects.h'47,48: Use of "void *" for object data defeats compiler type-checking and is not generally good practice. At a guess, shouldn't object handle be of type "struct nwam_handle *"? object_data could be pointer to a union or just a union (does object_data need to be allocated separately?). | done |
| seb-026 | ncu.h'70-99: Members need some identifying prefix. E.g., I have no hope of getting at "flags" or "dhp" from cscope. Please go through all data structures and rectify this where necessary. | done |
| seb-027 | main.c'71: There's not much point in making this a global variable in main.c since it's only used in one place in conditions.c, but I'm wondering why it's not initialized by an SMF property like other timer-related intervals. | done |
| seb-028 | main.c'71: Related to wlan_scan_interval, if the user manually selected a specific WLAN link, I would think that the daemon doesn't scan every 120 seconds. For some WiFi drivers, initiating a scan can have really strange side-effects, including blocking data for extended periods of time and experiencing link flaps. It would be nice to have a mode where the daemon doesn't continually scan for no reason. | RFE |
| seb-029 | main.c'82: And that nice README that comes with the source... | done |
| seb-030 | main.c'143: This isn't used outside of main.c and should be static. In accordance to csctyle guidelines, it also needs to go at the top of the file with other globals. | done |
| seb-031 | main.c'170: refresh() calls nwamd_init_ncus() along with other nwamd_init_<stuff>() functions. Do these init routines handle cleaning up the existing objects before initializing? If they clean up, then why is nwamd_fini_ncus() called on line 169? If they don't, then why don't we need to call nwamd_fini_<stuff>() before the refresh() call on 173? | BUG |
| seb-032 | main.c'172: I'm wondering why SIGHUP is any different from SIGTHAW. Shouldn't both signals essentially result in re-creating the nwamd universe from scratch as if it were starting anew? | BUG/EXPLAIN |
| seb-033 | main.c'242: There's no need for any of these local variables; you can pass the addresses of the global variables into nwamd_lookup_boolean_property(). | BUG |
| seb-034 | main.c'288: Consider renaming to nwamd_refresh() for easier cscope browsing. | done |
| seb-035 | main.c'347: I may be misunderstanding how this works, but what is the point of enqueuing an event here if the daemon is immediately going to exit() (the event might still be in the queue when that happens). Did I miss something? | EXPLAIN |
| seb-036 | main.c'414: I don't see how zonename is used anywhere. It should probably be removed (along with nwamd_lookup_zonename()). | done |
| seb-037 | main.c'424: Using dladm_status2str() to include additional information would be good. | BUG |
| seb-038 | main.c'444: What's this SOFT_RESET_FILE about? It doesn't look like it's used anywhere. | EXPLAIN |
| seb-039 | main.c'480: door_initialize() should return an error code that can be converted to a printable string passed to pfail(). Another approach would be to have door_initialize() pfail() upon failure and have it return void (which is what you do for other init routines). | BUG |
| seb-040 | main.c'481: What kind of error handling did you have in mind? |
EXPLAIN/BUG |
| seb-041 | door_if.c'73-776: The length of this function and its deep indentation makes it hard to read and thus review. I'd suggest processing of each request type in separate functions to help readability and reduce indentation. | RFE |
| seb-042 | door_if.c'85-88: what is this existentialist code about? If it's for lint, please remove this and use ARGSUSED instead. | BUG |
| seb-043 | door_if.c'91: Copying the data would aleviate the need for LINTED tags. | BUG |
| seb-044 | door_if.c'116,etc.: There's a lot of duplicate auth-checking code throughout this file. It might be simpler to have a simple table of door commands and associated required authorizations that could be checked prior to the switch. | RFE |
| seb-045 | door_if.c'133: Why is there no auth check for this command? | BUG/EXPLAIN |
| seb-046 | door_if.c'136: A WLAN scan request should require an authorization and/or elevated privileges, as it negatively impacts performance during the scan (severely for some drivers). The dladm scan-wifi subcommand requires sys_dl_config. | RFE/BUG |
| seb-047 | door_if.c'161: I believe that the res data is leaked here. door_return() never returns... Use alloca() instead. | done |
| seb-048 | door_if.c'177: What does this do? If it connects to a WLAN, then there should be some authorization check associated with this command. | RFE/BUG |
| seb-049 | door_if.c'214,308: The code for enable and disable is almost identical. I'm sure this could be refactored. | RFE |
| seb-050 | door_if.c'229: Why don't we record success for other audit checks in this function? Is that a bug? | BUG |
| seb-051 | door_if.c'251,281,345,375: This locking scheme to check for object state is at odds with the event queue scheme, and will likely lead to unexpected results. Locking the object to check its state cannot work reliably since there could be an event pending ahead of this request that changes the state immediately after you drop the lock and before you enqueue the event associated with this request. The NWAM_ENTITY_INVALID_STATE error returned by these door calls is thus meaningless. The state of the object cannot be reliably be checked until previous enqueued events are processed, and this event is dequeued. Given the event queue design, the best you probably can do is enqueue the request without checking the state, since you have no idea what the pending state of the object is (unless you can think of something better). | EXPLAIN |
| seb-052 | door_if.c'255,285,349: The same synchronization problem exists for these objects. There could be enqueued events that change the current active object, and thus checking the name of the current active object without consideration for pending events will lead to unexpected results. | EXPLAIN/BUG |
| seb-053 | door_if.c'255,285,349: The "active_loc" string could be in the middle of being modified by nwamd_loc_activate(). Same comment for the other strings being compared. | BUG |
| seb-054 | door_if.c'255,285,349: What verifies the input? The string could be non-NULL-terminated garbage. There should be a strlcpy() somewhere that verifies for overrun. | BUG |
| seb-055 | door_if.c'480-519: I don't see how this code can reliably work. Each action gets enqueued, so you have no way to verify if it succeeded. As such, the strategy of a rename operation being two separate operations (destroy and refresh) can result in an object being destroyed or a refresh action being processed when the destroy actually failed. | EXPLAIN/BUG |
| seb-056 | door_if.c'573,588: This doesn't take into account pending requests in the event queue. Those could very well be the requests from the door client to disable the very objects that it wants to destroy... | EXPLAIN/BUG |
| seb-057 | door_if.c'643: Why do you need a special case for the active location? Can it not be looked up using nwamd_object_find()? If yes, then you don't need that block of code. If not, then there's a race condition since "active_loc" could be in the process of being written to by nwamd_loc_activate(), which will result in an erroneous NWAM_ENTITY_NOT_FOUND. | BUG |
| seb-058 | door_if.c'791: I'd suggest using DOOR_REFUSE_DESC as well if you don't intent to handle file-descriptor passing through this door. | BUG |
| seb-059 | door_if.c'797: cstyle: need blank line between variables and code. | BUG |
| seb-060 | door_if.c'827: You could make doorfd a global I suppose, and you could close it | BUG |
| seb-061 | coditions.c'49: Yes, conditions are usually conditional. |
BUG |
| seb-062 | coditions.c'94: Need block comment explaining what this does. | BUG |
| seb-063 | coditions.c'111,113: I don't grok this code. What does NWAM_CONDITION_IS mean? This looks needlessly complicated. Why not just have a function that returns the state of the object and have the caller do what it wants with it... | EXPLAIN/BUG |
| seb-064 | coditions.c'565: "ret" is not descriptive enough given that it has deeper semantics. It represents the state of some object. | BUG |
| seb-065 | coditions.c'608: There should be a comment somewhere (perhaps at the top of this file) explaining what CONDITIONAL_ANY and CONDITIONAL_ALL mean. I'm really not sure what this is designed to do. | BUG |
| seb-066 | dlpi_events.c'58,87: Please give these more distinguished names. | BUG |
| seb-067 | dlpi_events.c'67: IFF_UP is an IP interface flag; it is not a link state. There is a link_state_t defined in <sys/mac.h> that you can use for this purpose. | BUG |
| seb-068 | dlpi_events.c'82-84: This needs further clarification in the comment. You're only interested in notifications, and notifications are only processed in a pending dlpi_recv(). As such, you need to continuously call dlpi_recv() even if you're not interested in any other DLPI messages. | BUG |
| seb-069 | dlpi_events.c'99: This needs some comments, as I'm not clear on what it implies. Does the DLPI notification thread for this link simply vanish if it gets three consecutive read errors? What happens to the rest of the handling for that link if that happens? | BUG |
| seb-070 | dlpi_events.c'103: Need block comment. | BUG |
| seb-071 | dlpi_events.c'116: This can't possibly happen, right? Shouldn't this be an assert()? | BUG |
| seb-072 | dlpi_events.c'131,144,156,167: It would be simpler and less error-prone to declare a name string of appropriate size on the stack, and have nwam_ncu_typed_name_to_name() (that's quite a mouthful) use it instead of having it dynamically allocate memory. | BUG |
| seb-073 | dlpi_events.c'130,142,154: The use of errno in these locations is a bug: dlpi_open() only sets errno if the error is DL_SYSERR. You should use dlpi_strerror() on the returned libdlpi error code to print something meaningful, it handles this cleanly. | done |
| seb-074 | enm.c'50: Please elaborate a little bit here and explain what an "external network modifier" abstraction is. | BUG |
| seb-075 | enm.c'123: You're leaking object_name here. | done |
| seb-076 | enm.c'134: You make this lengthy check numerous times in this function. I'd suggest defining a boolean_t called goingonline (or something like that) as a local variable and setting it to (object->object_state == NWAM_STATE_OFFLINE_TO_ONLINE). | RFE |
| seb-077 | enm.c'165: The only possible first argument for nwamd_start_child() is CTRUN (nwamd_start_child() is only called in this one location), so it might as well be implied and not be explicitly passed in. | BUG |
| seb-078 | enm.c'241: What prevents another thread from getting a reference to this object after you've dropped the lock and before you blow it away by calling nwamd_object_fini()? I don't see how this is safe. Has this code been stress-tested? | BUG |
| seb-079 | enm.c'368-390: This code is identical to 304-323. This could be factored out into its own function. | RFE |
| seb-080 | enm.c'461: Need a block comment; check for what? | BUG |
| seb-081 | enm.c'572: Replace all of the "return (0);" calls in the above switch with proper "break;" calls, and you won't need this NOTREACHED lint comment. | EXPLAIN |
| seb-082 | enm.c'569: You don't need this default case. | BUG |
| seb-083 | enm.c'625: You unlock the object here, but proceed to read and write to its state afterwards. This doesn't look safe. | BUG |
| seb-084 | events.c'476,509: Stashing the user context like this is obsoleted by dtrace and mdb, and neither of those need to have debug enabled to work. Can we lose this? | EXPLAIN/BUG |
| seb-085 | events.c'477: s/returned/return/ | BUG |
| seb-086 | events.c'481,519,550,etc.: Since this isn't a PTHREAD_MUTEX_ERRORCHECK mutex, failure of pthread_mutex_lock() is impossible. | BUG |
| seb-087 | loc.c'201: Need block comment: check what? | BUG |
| seb-088 | loc.c'224,227: This would be simpler as:
err = nwam_value_get_uint64(activationval, &activation);
nwam_value_free(activationval);
if (err != NWAM_SUCCESS) {
nlog(...);
return (0);
}
|
BUG |
| seb-089 | loc.c'349: This doesn't look right since another thread could be modifying active_loc. | BUG |
| seb-090 | ncu.c'51,1138: This doesn't look kosher at all. Basing functionality on link names is not correct. There looks to be some architecture missing here. | ARCH/BUG |
| seb-091 | ncu.c'191: Holding the link open is a problem for DR. This will need to eventually be addressed. This is a more general problem than just the DLPI interaction, obviously (I'm not sure how the existing rcm code interacts with nwamd's configuration of IP interfaces). The overall NWAM interaction with DR will need to be investigated fully in order for these two features to interoperate. Please file an RFE to track this. | RFE/ARCH/BUG |
| seb-092 | ncu.c'1427: It looks like some other thread can sneak in and grab a reference to this object after it's been unlocked and before it's blown away by nwamd_object_fini(). | BUG |
| seb-093 | ncu.c'1513-1528: This could all be collapsed:
case NWAM_STATE_OFFLINE_TO_ONLINE:
case NWAM_STATE_ONLINE_TO_OFFLINE:
case NWAM_STATE_ONLINE:
nwamd_ncu_state_machine(event->event_object);
break;
|
BUG |
| seb-094 | ncu.c'1545: Won't doing this after the object lock is dropped result in potential out-of-order issues with these calls? | BUG |
| seb-095 | ncu_ip.c'89: This function leaks both "request" and "reply". | done |
| seb-096 | ncu_ip.c'271: I think this needs to be newh. Otherwise, you're setting the broadcast on logical unit 0, and not the address that was created. | BUG |
| seb-097 | ncu_ip.c'540-582: The strategy used to figure out if a logical interface is needed or if it's the first address seems error prone and certainly not thread safe (although I'm not sure if thread safety is a concern for this function). This seems to be needed as a side-effect of the distinction between the newly introduced icfg_add_ipaddr() vs. icfg_set_addr() functions. It should be possible to fix this by defining a single icfg_add_addr() function that just does the right thing. On a related note, why is one _ipaddr() and the other _addr()? |
BUG |
| seb-098 | ncu_ip.c'700: There's a XXX here. | BUG |
| seb-099 | ncu_ip.c'722: A cleaner interface would be two separate functions, a plumb function and an unplumb function. They can share the same implementation if necessary, but at least the callers won't be saddled with a huge ambiguous function name and needless boolean argument. | BUG |
| seb-100 | ncu_phys.c'69: The caller should pass in a buffer of size LIFNAMSIZ; there's no reason for this function to dynamically allocate memory. It could then return void and callers wouldn't need to handle failure. | BUG |
| seb-101 | ncu_phys.c'132: Similar to my comment on the plumb_unplumb() function, this really should be two functions whose names are indicative of what they do instead of one ambiguous one with a boolean argument that indicates what it should do. | BUG |
| seb-102 | ncu_phys.c'185: There's a XXX here. | BUG |
| seb-103 | objects.c'195: pthread_rwlock_wrlock() can't possibly fail. If it fails, then it's because there's a bug in your code and you might as well abort(). | BUG |
| seb-104 | objects.c'396: nwamd_object_fini() must not fail. It is called in a context where failure is not an option (there is no way to recover from such a failure). This must be rectified. It looks like every caller ignores the return value, so it looks like someone already knew that this was wrong... | BUG |
| seb-105 | util.c'241: Isn't this a little too late? zone_check_datalink() verifies if a link belongs to a running zone, but nwamd holds all links open when it starts, which is before zones boot. As such, the zone that needs this link won't be able to use it (a link's zone property can't be set if the link is open). I don't see how this works. Maybe I'm not seeing the bigger picture. How can an exclusive stack zone boot propertly while nwamd is running? | BUG |
| seb-106 | util.c'521: A safer model (one less prone to memory leaks) is one where the caller passes in an appropriately-sized buffer to store the answer. | done |
libnwam/netcfgd
| Reviewer/ID | Comment | Status |
|---|---|---|
| meem-064 | netcfgd'Unclear why this consists of multiple source files; it seems like everything could be consolidated into a single source file without sacrificing maintainability. | done |
| meem-065 | netcfgd/Makefile'29-30: Pulling in Makefile.lib seems wrong since that's for building libraries. Just use $(ROOT)/lib. | done |
| meem-066 | netcfgd/Makefile'35: Remove needless HEADERS definition. | done |
| meem-067 | netcfgd/Makefile'61: What does this $(ROOTCMD) dependency do? | done |
| meem-068 | netcfgd/util.h'Given that this only has logging functions, seems odd it's named util.h. (But then again, I can't figure out why this exists.) | done |
| meem-069 | netcfgd/util.h'33: Need a /* PRINTFLIKE2 */ here. | done |
| meem-070 | netcfgd/util.h'39: No externs, please. | done |
| meem-071 | netcfgd/logging.c'28-29: Unclear what this comment has to do with anything; no debug.c here. | done |
| meem-072 | netcfgd/logging.c'42: s/The idea for having this function is so that you can /This function allows you to/ | done |
| meem-073 | netcfgd/logging.c'43: s/Its/It's/ | done |
| meem-074 | netcfgd/logging.c'59: Why 256? Why not vasprintf()? | done |
| meem-075 | netcfgd/logging.c'81-90: Could be replaced with (in util.h)
#define dprintf(...) nlog(LOG_DEBUG, __VA_ARGS__) |
done |
| meem-076 | netcfgd/main.c'General: I can't figure out what the zonename code is for; we never seem to use the `zonename' variable. My nits below assume that somehow it's supposed to do something. | done |
| meem-077 | netcfgd/main.c'28: Comment should provide an overview of what this daemon does on a technical level. | done |
| meem-078 | netcfgd/main.c'32, 34, 38, 39, 40, et al: Superfluous #includes | done |
| meem-079 | netcfgd/main.c'51, 52: No excuse for these being globals. | done |
| meem-080 | netcfgd/main.c'57-59: Unclear what this comment has to do with anything. | done |
| meem-081 | netcfgd/main.c'68: Where does this code lookup SMF properties? | done |
| meem-082 | netcfgd/main.c'70: Where does this code manage privileges? | done |
| meem-083 | netcfgd/main.c'76: Is there a reason this uses LOG_NDELAY? | done |
| meem-084 | netcfgd/main.c'79-113: Someone really needs to put this in a library |
done |
| meem-085 | netcfgd/main.c'124: Prefer const. | done |
| meem-086 | netcfgd/main.c'126: No need to define `zoneid'; just inline the call to getzoneid() int the getzonenamebyid() call. | done |
| meem-087 | netcfgd/main.c'132: Why is it correct to charge on with GLOBAL_ZONENAME in this case? | done |
| meem-088 | netcfgd/main.c'141-142: Just curious: what exactly are we localizing? All of the messages here go to syslog which is not localized. | done |
| meem-089 | netcfgd/main.c'145: Why is this LOG_INFO? Seems like LOG_DEBUG. Also, LOG_PID was specified to openlog() so I'm not sure why this includes the pid as well. Finally, the message should be generated in start_logging(), not here. | done |
| meem-090 | netcfgd/main.c'149-155: Indenting here is one level off. | done |
| meem-091 | netcfgd/main.c'162: Comment states the obvious. | done |
| meem-092 | netcfgd/main.c'166-168: Unclear why we want to ignore USR1/USR2/INT. | done |
| meem-093 | netcfgd/main.c'170: Need to resolve this XXX for SIGTHAW. | done |
| tony-15 | I have another concern regarding location-based IPfilter configuration. The current implementation requires users to supply a customized ipf rules for every location if they want to configure IPfilter. This essentially undo the functionality of Host-based firewall which simplified IPfilter configuration. We ought to allow users to configure location with the option of using their existing IPFilter configuration, in fact, I'd argued that option should be the default. | |
| sowmini-03 | it's hard to figure out which libnwam interfaces are "truly" exported, and which ones are there because they are shared between some daemon and libnwam. The nwam_backend_init is an example of the latter, which ends up in mapfile-vers as globally exported just so that the daemon can also use it. We need to find a better solution for the latter case (see comments for libnwam.h) | |
| sowmini-04 | netcfgd/Makefile: dlmgmtd runs as OWNER dladm, group sys. What are the owner/group of netcftd (I'd guess that the owner would be netcfg- but inside the code it seems to use netadm, and invokes getpwam etc. - why the divergence from dlmgmtd)? | DISCUSS (thread) |
| sowmini-05 | netcfgd/Makefile: do we need to define ROOTCFGDIR/<configfile> permissions? | |
| sowmini-06 | netcfgd/logging.c: see relevant comments for netcfgd/main.c | |
| sowmini-07 | netcfgd/main.c: fg can be a local variable to main() - it is not used outside the main() context. | |
| sowmini-08 | netcfgd/main.c: debug doesn't need to be extern global, it can be static to logging. but perhaps it is not needed at all? How is one supposed to set it? (One suggestion, always have syslog support, but use SIGUSR1/SIGUSR2 handlers to make it more/less verbose by incr/decr debug) | |
| sowmini-09 | zonename does not need to be a global var: it's only usage is for lookup_zonename, and there it is passed as an argument. | |
| sowmini-25 | linbwam/Makefile: ok except for similar question about the check target as for inetcfg/Makefile | |
| sowmini-26 | libnwam_audit.c'69: do you need to adt_free_event() and adt_end_session()? | |
| sowmini-27 | libnwam_audit.c'49: do you need to adt_end_session()? | |
| sowmini-28 | libnwam_backend.c: how does nwam_backend_door_server work (doesn't it end up doing door_return 2 times?): on receiving some NWAM_BACKEND*REQ, it sets up cmd = NWAM_BACKEND_*RES, and then goes to nwam_create_backend_door_arg which will do a door_return at line 181. Then nwam_backend_door_server() will again do a door_return at line 325, right? | |
| sowmini-29 | libnwam_backend.c'nwam_backend_init(): lines 349-360. dlmgmtd had some issues with the filesystem not being writable early in boot. How does nwamd work around that problem? | |
| sowmini-30 | libnwam_backend.c'382: if fattach() fails, we should door_revoke() the DOOR_FILE. | |
| sowmini-31 | libnwam_backend.c: nwam_backend_exit() is something that is only used by netcfgd, and it registers an atexit() callback, so it doesn't look like it belongs in a general "libnwam/common" file.. this should be made local to netcfgd/*.c itself. | |
| sowmini-32 | libnwam_backend.c: should this be 0755
358 (chmod(NWAM_DOOR_DIR, 07555) < 0 || |
|
| sowmini-33 | libnwam_backend.c: make_door_call() is a rather generic function name (and libscf also has this). Suggest nwam_make_door_call() or nwam_door_call() instead. | |
| sowmini-34 | libnwam_impl.h: please use unique prefixes for fields to aid cscope. e.g, use nwh_ as the prefix for fields in struct nwam_handle, nwv_ for struct nwam_value fields. Just the simple "name" field is currently used in 5 different structures even withing libnwam_impl.h itself. | |
| sowmini-35 | libnwam_impl.h: nit:
56 struct nwam_value
57 {
should be collapsed to one line:
56 struct nwam_value {
|
|
| sowmini-36 | libnwam_impl.h: please add some comments explaining what the various fields in nwam_backend_door_arg are (e.g., arg_parent, arg_object etc.) and what the layout of the data passed between client and server looks like | |
| sowmini-37 | libnwam_impl.h'370: nit: s/ist/list | |
| sowmini-38 | libnwam_files.c'value_add_escapes(): instead of repeatedly doing malloc/free around this function, the caller can pass in the output array with its size. another alternative is for value_add_escapes() to create out by doing a strdup(in) similarly for value_remove_escapes() | |
| sowmini-39 | libnwam_enm.c'nwam_enm_handle_create: is this function live? it's not exported via mapfile-vers or libnwam.h, and there are no internal calls to it? Functions that seem to need it (e.g., nwam_enm_read) seem to eventually create the handle by calling nwam_handle_create itself. If it's not needed, nwam_enm_handle_create should be removed. | |
| sowmini-40 | libnwam_enm.c'nwam_enm_set_name(), nwam_enm_get_prop_type() also appear dead. | |
| sowmini-41 | libnwam_enm.c:How does nwam_enm_handle_create verify its args (e.g., that name is null terminated, non-null etc)? Same question applies to nwam_enm_read() which is exported, so could get anything for its args. Minimally it should take a name_size argument in addition to the char *name. Sanity checking of flags wold also be a good thing. | |
| sowmini-42 | libnwam_known_wlan.c'nwam_known_wlan_handle_create() | |
| sowmini-43 | libnwam_loc.c'nwam_loc_handle_create(): is this function live? not exported, and no calls to it? See comments for libnwam_enm.c | |
| sowmini-44 | libnwam_loc.c'nwam_loc_validate(): where is char *name freed? | |
| sowmini-45 | libnwam_loc.c'325-331: please move these definitions to the start of the file- they seem to be sprouting in random places. | |
| sowmini-46 | libnwam_ncp.c: nwam_ncp_get_read_only() leaks char *name | done |
| sowmini-47 | libnwam_object.c: please add comments before each function, explaining input/output and expected returns from these functions. The "parent" term, for example, is not inutitive- it seems like this is the name of the configuration file/db from which the backend is supposed to read/write- is that correct? If yes, it would be more obvious to rename "parent" to "dbname" or "conf_file". Using the term "parent" for this makes it sound like there would be a related "child", which is not the case here (for file-store). | |
| sowmini-48 | libnwam_object.c'1445-1460 please move these definitions to the start of the file | |
| sowmini-49 | libnwam_object.c'1768-1769: why have NWAM_IP_VERSION_IPV4/NWAM_IP_VERSION_IPV6 when IPV4_VERSION and IPV6_VERSION are available? | |
| sowmini-50 | libnwam_object.c: doesn't valid_link_mtu have to check if the mtu is within the acceptable range for the link? More generally, I would think that the signature of the prop_validate function would need more args to verify against libdladm, etc.? | |
| sowmini-51 | libnwam.h: what is NWAM_FLAG_GLOBAL_MASK used for? Should this just be "-1"? | |
| sowmini-52 | libnwam.h: why the extra level of indirect for NWAM_WALK_FILTER_MASK? Can't we just have "#define NWAM_WALK_FILTER_MASK (0xFFFFFFFFULL << 32)" | |
| sowmini-53 | libnwam.h: use parentheses around NWAM_FLAG_NCU_TYPE_LINK, NWAM_FLAG_NCU_TYPE_INTERFACE But a bigger question is - why are these being shifted out by 32 (i.e., what's in the low order bits, and why is it so complex?) | |
| sowmini-54 | libnwam.h: need parentheses around NWAM_FLAG_NCU_CLASS_* definitions. But the class definitions are confusing: on the one hand PHY and IPTUN seem to be a subset of datalink_class_t (and therefore mutually exclusive), but then there's CLASS_IP (which applies to any datalink_class_t). How are distinctions drawn here? At the very least, some comments would be needed to explain when/how these should be specified. | |
| sowmini-55 | libnwam.h: it's unfortunate that nwam_backend_init and nwam_backend_fini are exposed as global interfaces to any application that links libnwam, when really, all that's needed is to share them between libnwam and netcfgd. I'm not sure if SUNWprivate can be used here |
|
| sowmini-56 | nwam_addrsrc_t: fyi, Brussels is introducing similar definitions. Perhaps it would be useful to extract this to a common file that can be shared by both libraries (and without any NWAM_* prefix)? | |
| sowmini-57 | NWAM_STATE*STRING definitions do not have to be exposed via libnwam.h: should be mapped using a {code, string} array line nwam_errors that's used by nwam_state_to_string(); see related comments about libnwam_util.c. The same thing applies to
nwam_aux_state_t, NWAM_AUX_STATE*STRING, nwam_activation_mode_t, NWAM_ACTIVATION_MODE_*STRING, nwam_condition_t, NWAM_CONDITION*STRING, nwam_condition_object_type_t, NWAM_CONDITION_OBJECT_TYPE*STRING nwam_configsrc_t, NWAM_CONFIGSRC_*STRING nwam_nameservices_t, NWAM_LOC_PROP* nwam_ncu_type_t, NWAM_NCU_TYPE*STRING nwam_ncu_class_t, NWAM_NCU_CLASS_*STRING nwam_iptun_type_t, NWAM_IPTUN_TYPE*STRING nwam_addrsrc_t, NWAM_ADDRSRC*STRING, nwam_priority_mode_t, NWAM_PRIORITY_MODE*STRING |
|
| sowmini-58 | nwam_iptun_type_t can just use clearviews' iptun_type_t? | |
| sowmini-59 | libnwam_util.c: the nwam*_to_string functions should use {code, string} arrays like nwam_errors[]. In fact, there can be one nwam_code_to_string_internal() that takes the {code, string} array and code as args, and returns the const char * as the result. Then the nwam_code_to_string_internal() (which would be a generalized version of nwam_strerror()) could be shared by nwam_object_type_to_string etc. and this would also consolidate the dgettext calls. | |
| seb-107 | libnwam_events.c'284: Block comment needed: what does this do? | |
| seb-108 | libnwam_ncp.c'553: Having the caller pass in a buffer and buffer length is a better model, as it is less prone to memory leaks. |
CLI (nwamcfg, nwamadm) (Anurag) [nwamadm thread, nwamcfg thread]
| Reviewer/ID | Comment | Status |
|---|---|---|
| meem-004 | nwamadm/Makefile'Given the way gettext() is used in nwamadm, you need something like XGETFLAGS += -a -x $(PROG).xcl and an nwamadm.xcl file. | done |
| meem-005 | nwamadm/Makefile'34: Why is LFLAGS set in here? | done |
| meem-006 | nwamadm/Makefile'36: -I. is wrong; local header files should be included with `#include "local.h"'. | done |
| meem-007 | nwamadm/Makefile'30: Needless; source is only built from one file. | done |
| meem-008 | nwamadm/Makefile'42-44: Needless rules. | done |
| meem-009 | nwamadm/Makefile'55: Why not use lint_PROG? | done |
| meem-010 | nwamadm.c'Throughout: the ofmt API needs to be used to print stuff out rather than rolling your own printing logic. This will also provide parsable mode and user-selectable fields for free (which currently seem to be missing). | RFE |
| meem-011 | nwamadm.c'Throughout: what's up with the name zerr()? Am I to assume it's because this code started life as zoneadm.c? Seems like it should be called die(), and seems like you could also use a die_nwamerr() function that takes a nwamerr and does the nwam_strerror() a la die_dlerr() in dladm. | done |
| meem-012 | nwamadm.c'Throughout: seems a shame that the libnwam walker APIs require a non-NULL cb_ret argument, as nothing here seems to want to consult it. Why not allow it to be NULL? | RFE |
| meem-013 | nwamadm.c'50: Needless blank line. | done |
| meem-014 | nwamadm.c'58, 64-72: The use of both command numbers and an array of command entries seems muddled. Seems like all the functionality tied to command numbers could be folded into state tracked in the command entries – e.g., a cmd_help pointer-to-function (or just a simple const char *), and a flags field that indicates whether e.g. "-x" can be used or whether the type needs to be determined. | done |
| meem-015 | nwamadm.c'60: Should be cmd_handler for consistency. | done |
| meem-016 | nwamadm.c'60: Should define a typedef for this – e.g.:
typedef int (cmd_handle_func_t)(int, char **); ... then declare cmd_handler as a pointer to this, and the declarations on 79-84 as instances of this type. |
done |
| meem-017 | nwamadm.c'77: Seems like this FMRI should be in a library header. | done |
| meem-018 | nwamadm.c'151: Unclear why this is a global; seems like it should be declared in interact_func() and passed to eventhandler(). | done |
| meem-019 | nwamadm.c'167-277: I'd expect these helper routines to be in libnwam rather than nwamadm. Some of them already appear to be there, such as nwam_ncu_type_to_flag(). Why are they here? | done |
| meem-020 | nwamadm.c'179, 193, 215, 230, 246, 262, 275, 297: The default cases here seem unhelpful. I'd expect strings of "?" and enumerations along the lines of NWAM_OBJECT_TYPE_UNKNOWN. | done |
| meem-021 | nwamadm.c'209: Presumably this should be "ncu"? | done |
| meem-022 | nwamadm.c'323: Presumably this should be ""%s: <subcommand>". | done |
| meem-023 | nwamadm.c'368, 371: This seems like abuse of return values, as NWAM_WALK_HALTED and NWAM_SUCCESS do not appear to be intended for this use. Instead, it seems that the walker should return 0 or 1. |
done |
| meem-024 | nwamadm.c'378: Why is it safe to ignore the return value from this function? Is it that we assume `state' will only be modified by this function call upon success? Seems a needless assumption. | done |
| meem-025 | nwamadm.c'451: Would seem more natural to return `type' and remove the `num' parameter in place of an NWAM_OBJECT_TYPE_UNKNOWN value. | done |
| meem-026 | nwamadm.c'514: This seems unnecessarily obscure; don't we know cmd_to_str(CMD_LIST) == "list"? | done |
| meem-027 | nwamadm.c'549-558: Seems like this would just be:
if (cmd_num != CMD_LIST && type == NWAM_OBJECT_TYPE_NONE) |
done |
| meem-028 | nwamadm.c'560: Needless cast. | done |
| meem-029 | nwamadm.c'653-684: This should be factored out into a funciton that takes the type and then is merely called here for NWAM_NCU_TYPE_LINK and NWAM_NCU_TYPE_INTERFACE. For bonus points, could take a function pointer which would be either &nwam_ncu_enable or &nwam_ncu_disable. | done |
| meem-030 | nwamadm.c'651, 690, 693: Should be a switch statement with NWAM_SUCCESS, NWAM_ENTITY_MULTIPLE_VALUES and default. | done |
| meem-031 | nwamadm.c'705-715: Can factor this out to a function and reuse this code with disable_func(). For I18N to work, you need to restructure the messages – e.g.: "cannot enable: <blah>" – then you'll end up parameterizing the subcommand name (which won't be translated). | done |
| meem-032 | nwamadm.c'719: By the time we get here isn't the enable complete? That is, seems like this should be "Enabled", not "Enabling". | done |
| meem-033 | nwamadm.c'724: `if' block should be replaced with assert(ret != NWAM_SUCCESS)' and the code should be unindented. | done |
| meem-034 | nwamadm.c'785-868: See previous comments regarding enable_func() code. | done |
| meem-035 | nwamadm.c'871: Would seem preferable to return a error code indicating whether the function succeeded rather than overloading *_UNINITALIZED for the job. | done |
| meem-036 | nwamadm.c'872, 934: Everything that uses determine_object_state() immediately then calls add_to_profile_entry(). Seems like it would be simpler to have add_to_profile_entry() get the state itself rather than taking `state' and `auxstate' arguments. | done |
| meem-037 | nwamadm.c'928: How do we get here? Seems like we should assert(0). | done |
| meem-038 | nwamadm.c'932: p_entries is a linked list, not an array. | done |
| meem-039 | nwamadm.c'956: p_last_entry is gross. Does the order of the list matter? If not, why not prepend to the list? If so, would prefer to make the list circular and use p_prev. | done |
| meem-040 | nwamadm.c'979, 1020, 1058, 1090: Needless cast. | done |
| meem-041 | nwamadm.c'986, 988: `name' appears to be leaked. | done |
| meem-042 | nwamadm.c'988: `val' appears to be leaked. | done |
| meem-043 | nwamadm.c'1108-1156: See previous comments about using ofmt. As an aside, the field names are generally considered part of the command itself and are not something we translate – and this is important when -o <field> is supported. | RFE |
| meem-044 | nwamadm.c'1165-1166: Needless "optimization". | done |
| meem-045 | nwamadm.c'1196-1199: No voodoo code, please. | done |
| meem-046 | nwamadm.c'1207, 1219, 1227, 1234: Needless cast. | done |
| meem-047 | nwamadm.c'1250, 1251: Useless comments. | done |
| meem-048 | nwamadm.c'1260-1475: This function is really hard to read – and again, ofmt should be used to print output. | RFE |
| meem-049 | nwamadm.c'1260-1475: Is this intended as a debugging aid or something that end-users would actually use? If the latter, seems like some I18N handling is missing in the various prompts. Also, how is the end-user supposed to make sense of the stuff output from this? Further, it seems odd to me that the interactive support and event monitor have been glommed together into one facility. | done |
| meem-050 | nwamadm.c'1266: `action' should be declared properly as a `const char *' and the bogus casts on line 1278, 1422, and 1449 should be removed. | done |
| meem-051 | nwamadm.c'1338, 1346, 1388: This works without fflush(stdout)? | done |
| meem-052 | nwamadm.c'1338, 1346, 1388: Can the user ^C out? If so, how does that work? If not, seems a usability problem. | done |
| meem-053 | nwamadm.c'1366, 1402: Why are errors going to stdout? | done |
| meem-054 | nwamadm.c'1378, 1388: Would expect a space after the ":". | done |
| meem-055 | nwamadm.c'1432: How do you know this is a sockaddr_in? Sure looks like this code can be reached with a sockeddr_in6. | done |
| meem-056 | nwamadm.c'1474: Remove blank line. | done |
| meem-057 | nwamadm.c'1511: See previous comment about I18N with field names. | done |
| meem-058 | nwamadm.c'1515-1528: Odd code here seems to stem from mixing interaction and event monitoring. | done |
| meem-059 | nwamadm.c'1543: strdup() can fail. This is the problem with using basename(3C) rather than just doing the typical:
if ((execname = strrchr(argv[0], '/')) == NULL)
execname = argv[0];
else
execname++;
You can also remove the <libgen.h> #include and -lgen link. |
done |
| meem-060 | nwamadm.c'1551-1554: This means one cannot observe the events at NWAM startup with "interact" which seems unfortunate. | done |
| meem-061 | nwamadm.c'1531: So using the "interact" subcommand always exits with a non-zero status? | done |
| meem-062 | nwamadm.c'1547, 1554, 1565: Would be clearer as EXIT_FAILURE. | done |
| meem-063 | nwamadm.c'1556: I suppose it doesn't matter much, but `state' is leaked. | done |
| meem-109 | nwamcfg.c: many of the same comments I made for nwamadm apply to this file – e.g., zerr(), die_nwamerr(), CMD_* vs command tables, etc. In the interest of brevity, I have not repeated previous comments that apply directly to nwamcfg (e.g., problematic use of basename()). | added, no exit() though |
| meem-110 | nwamcfg.c: a lot of very repetitious code – I have enumerated a number of instances below. FWIW, a lot of these issues are due to the libnwam API itself – e.g., sets of parallel functions that differ only in the handle they take and their name. It seems like an OO design would've simplified the code considerably – e.g., each object could've had an ops vector associated with it that the various callers could use without repeatedly concerning themselves with the type of the object. | cleaned up |
| meem-111 | nwamcfg.c: because of the above, I have mostly focused on smaller opportunities for code cleanup. That is, I find the libnwam API problematic because it leads to rampant duplication and code sprawl for consumers like nwamcfg, but aside from a couple of examples to explain what we could be done "someday" I have avoided commenting on it unless I have a specific and straightforward suggestion for streamlining the code. | done |
| meem-112 | nwamcfg.c: assorted uses of printf() without localization. (e.g., 918-920, 1984, 3060, 4331, 4335, ...) | no need |
| meem-113 | nwamcfg.c: assorted spurious ARGSUSED directives – e.g.: 3051, 3076, 3101, ... | done |
| meem-114 | nwamcfg.c: the various got_*_handle globals seem unnecessary; shouldn't we be able to just check if the handles are NULL? | done |
| meem-115 | nwamcfg.c: numerous calls to check_scope() could be more simply handled by the function dispatcher, rather than repeated in each *_func(). | done |
| meem-116 | nwamcfg.c: several blocks of code have something like:
if (got_enm_handle) {
prop_type = pt_to_prop_type(pt_type, NWAM_OBJECT_TYPE_ENM);
if (prop_type == NULL)
goto prop_error;
/* check if property can be set */
if (is_prop_read_only(prop_type, NWAM_OBJECT_TYPE_ENM))
goto read_only;
if (!show_prop_test(prop_type, enm_prop_display_entry_table,
NWAM_OBJECT_TYPE_ENM))
goto skip_prop;
/* ... */
} else if (got_wlan_handle) {
prop_type = pt_to_prop_type(pt_type,
NWAM_OBJECT_TYPE_KNOWN_WLAN);
if (prop_type == NULL)
goto prop_error;
/* check if property can be set */
if (is_prop_read_only(prop_type, NWAM_OBJECT_TYPE_KNOWN_WLAN))
goto read_only;
if (!show_prop_test(prop_type, wlan_prop_display_entry_table,
NWAM_OBJECT_TYPE_KNOWN_WLAN))
goto skip_prop;
/* ... */
} else if (got_ncu_handle) {
/* ... */
This code could be simplified significantly if there was a function that consulted the various handles to determine which one was live and returned the appropriate object type. Then you could do something like: handle_type = get_handle_type();
if ((prop_type = pt_to_prop_type(pt_type, handle_type)) == NULL)
goto prop_error;
if (is_prop_read_only(prop_type, handle_type))
goto read_only;
if (!show_prop(prop_type, prop_table[handle_type], handle_type))
goto skip_prop;
... and only switch on the handle_type once you need to get into logic that cannot easily be parameterized. |
done, added active_object_type() |
| meem-117 | nwamcfg.c'32: I don't see any block comments near the end of nwamcfg_grammar.y. | removed reference |
| meem-118 | nwamcfg.c'163, 167, 187, 189, 193, 214: What is the significance of these comments? | removed |
| meem-119 | nwamcfg.c'219, 228, 236: Why are these arrays NULL-terminated? | removed |
| meem-120 | nwamcfg.c'240, 286, 304, 359: Why are these all different structures? They all have identical contents and field names. These should be folded into a common nwamcfg_prop_table_entry structure and all members should have a consistent prefix for easy cscoping. | done |
| meem-121 | nwamcfg.c'399: Seems like `output_file' could be local to export_func() and passed to the various walker callbacks via the walker callback argument. | done |
| meem-122 | nwamcfg.c'405: Seems like quoted_strings could just be an argument to output_prop_val(). | done |
| meem-123 | nwamcfg.c'447, 451, 455: Indeed, errors need to be reported. | done |
| meem-124 | nwamcfg.c'483: Doesn't seem to have anything in particular to do with strings – would expect `array_free(void **array, int nelem)'. | done |
| meem-125 | nwamcfg.c'962-986: Assumes English locale. | done |
| meem-126 | nwamcfg.c'1043: prompt[] only accounts for MAX_NWAM_TYPE_LEN once, but there can be two types. | done |
| meem-127 | nwamcfg.c'1084: Why is it safe to ignore the return value from string_to_yyin()? | not ignored |
| meem-128 | nwamcfg.c'1218-1265: Should be condensed to a single is_prop_listprop() function that takes the table pointer. (That said, I would've expected this attribute to be part of the object itself and thus tracked by libnwam rather than nwamcfg.) | moved to libnwam |
| meem-129 | nwamcfg.c'1355-1378: Mapping between NWAM classes and NWAM object types seems more suited to libnwam. | moved |
| meem-130 | nwamcfg.c'1390-1392: Under what situations do callers pass in NULL? | export_func(), list_func() |
| meem-131 | nwamcfg.c'1396, 1398: Crashes if strdup() fails. | done |
| meem-132 | nwamcfg.c'1418-1659: Most error paths in this function leak `newname'. | done |
| meem-133 | nwamcfg.c'1459-1519: Handling of `ret' can be centralized (cmd_res1_type and cmd_res2_type can be converted to strings if precise error messages are desired). | done |
| meem-134 | nwamcfg.c'1525-1625: Lots of repetitious parallel logic here. This is exactly the kind of code that would be simple and clear had libnwam associated an ops vector with its objects rather than having a set of equivalent but distinctly-named methods for every operation. | done |
| meem-135 | nwamcfg.c'1654-1655, 1925-1926, 1977-1978, 4859-4860, 2140: Shouldn't alloc_cmd() be able to guarantee this? | done |
| meem-136 | nwamcfg.c'1664: nit: s/than/the. | done |
| meem-137 | nwamcfg.c'1671-1738: Logic to process the return codes should be shared across these functions – e.g.:
int
destroy_ncp_callback(nwam_ncp_handle_t ncp, void *arg)
{
return (destroy_ret(nwam_ncp_destroy(ncp,
NWAM_FLAG_DO_NOT_FREE));
}
|
done |
| meem-138 | nwamcfg.c'1752-1764: What happens to nwamcfg when this to fails part-way through? | continues |
| meem-139 | nwamcfg.c'1778-1783: Given the way this function is used, it would seem simpler to change this be have_ncus() { return (1) } and have the caller check if the NWAM_WALK_HALTED was returned to determine whether or not the list was empty. | code removed |
| meem-140 | nwamcfg.c'1896: If nwam_ncp_walk_ncus() fails, it appears we delete the ncp regardless. | code removed |
| meem-141 | nwamcfg.c'1935-1955: Duplicates logic in cancel_func(). | factored out |
| meem-142 | nwamcfg.c'1973-1982: Duplicates logic in end_func(). | factored out |
| meem-143 | nwamcfg.c'2019-2052: Should be backed by a common implementation that takes a propname – but moreover, I'd expect these utility routines to be provided by libnwam. | moved |
| meem-144 | nwamcfg.c'2028, 2030, 2046, 2048: Returning -1 seems incorrect since it's out-of-range for the type. Would seem simplest to add e.g. NWAM_NCU_TYPE_UNKNOWN to the enums. | done |
| meem-145 | nwamcfg.c'2143, 3577: nit: Superfluous `return'. | removed |
| meem-146 | nwamcfg.c'2201, 2221: Leaks `name'. | done |
| meem-147 | nwamcfg.c'2223: nit: Superfluous blank. | removed |
| meem-148 | nwamcfg.c'2240-2344: This logic could be shortened considerably by having the table pointers stored in an array that's keyed by the type – i.e.:
int
prop_to_pt(const char *nwam_prop, nwam_object_type_t type)
{
nwam_prop_table_t *table;
assert(type >= 0 && type < NWAM_OBJECT_TYPE_KNOWN_WLAN);
table = prop_tables[type];
for (i = 0; table.prop_type != NULL; i++) {
if (strcmp(nwam_prop, prop_table[i].prop_type) == 0)
return (prop_table[i].type);
}
return (-1);
}
|
done |
| meem-149 | nwamcfg.c'2352: Why is that a reason for cutting and pasting this function? | removed, use from library |
| meem-150 | nwamcfg.c'2389-2399: Doesn't strtol() already provide this ability by checking if isdigit(*endptr)? | done |
| meem-151 | nwamcfg.c'2406: Why is `input_str' `const char *'? Doesn't seem like this function treats it as const (as per the logic on 2432-2443). | done |
| meem-152 | nwamcfg.c'2453-2467: val[] array is leaked. | done |
| meem-153 | nwamcfg.c'2543-2544: How will this value be maintained? Seems like nothing uses more than two values though. | maintained here |
| meem-154 | nwamcfg.c'2777-2780: `return (!prop_found)' seems simpler (if the concern is clarity, giving the boolean another name (like `show_prop') would help. | keeping it as show_prop |
| meem-155 | nwamcfg.c'2843: If there are none then why do we check? | done |
| meem-156 | nwamcfg.c'2923-3018: See previous comments regarding get_handle_type() for how this could be streamlined. | done |
| meem-157 | nwamcfg.c'3051-3151: Not to harp on this too much, but this is another instance where one really pines for an ops vector – e.g.:
int
list_obj_callback(nwam_obj_t *obj, void *arg,
const char *objname, const char *objplural)
{
char *name;
nwam_error_t ret;
boolean_t *list_msgp = arg;
if (*list_msgp) {
(void) printf("%s:\n", objplural);
*list_msgp = B_FALSE;
}
ret = (*obj->namefunc)(obj, &name);
if (ret != NWAM_SUCCESS) {
warn_nwerr("List error: cannot get %s", objname);
return (1);
}
(void) printf("\t%s\n", name);
free(name);
return (0);
}
... then e.g.:
int
list_enm_callback(nwam_enm_handle_t enm, void *arg)
{
return (list_obj_callback(enm, arg, "ENM", "ENMs"));
}
|
done |
| meem-158 | nwamcfg.c'3181-3258: This is really hard to read. One minor improvement would be to have the logic at 3193-3257 just build the string arrays, and have a single loop iterate through them at the end and centralize the fprintf() and NWAM_VALUE_DELIMITER_STR logic. | done |
| meem-159 | nwamcfg.c'3322-3334: Needs to share a common implementation with output_propname(). | done |
| meem-160 | nwamcfg.c'3322-3334: Shouldn't bisect the *_listprop() routines. | done |
| meem-161 | nwamcfg.c'3431, ...: nit: Why is list_msg local to each `if' clause? | done |
| meem-162 | nwamcfg.c'3556-3558: Why is this needed? | done |
| meem-163 | nwamcfg.c'3564: Shouldn't list_ncu_callback() already print this? | code removed |
| meem-164 | nwamcfg.c'3573, 4120: Superfluous check. | done |
| meem-165 | nwamcfg.c'3581-3590, 3671-3681, 3717-3727, 3769-3779: Functions can easily be consolidated into a single function that takes a type. | done |
| meem-166 | nwamcfg.c'3830-3832: L1 exports would be cleaner to implement as an export[] array indexed cmd_res1_type – e.g. 3915-3937 would essentially be:
if (cmd->cmd_res1_type == RT1_UNKNOWN) {
for (i = RT1_MIN; i < RT1_MAX; i++)
export_l1[i] = B_TRUE;
} else {
export_l1[cmd->cmd_res1_type] = B_TRUE;
}
|
done |
| meem-167 | nwamcfg.c'3888: Short comment explaining the purpose of the write_to_file check would be helpful. | done |
| meem-168 | nwamcfg.c'4166-4191: See previous comments about get_handle_type(). | done |
| meem-169 | nwamcfg.c'4244-4275: See previous comments about get_handle_type(). | done |
| meem-170 | nwamcfg.c'4296: How can we get here with prop_type != NULL? | done |
| meem-171 | nwamcfg.c'4343-4611: Significant amount of duplicate code here that should be refactored – e.g., lines 4356-4362, 4426-4432, 4493-4500, 4568-4574 all identical (and seems like functionality that could partially be built into output_prop_val()), and much of the user input processing could be factored out to a common function and parameterize based on the type. | done |
| meem-172 | nwamcfg.c'4338-4340: Seems more complex to do it this way than to just have 4332 and 4335 print the closing brace. | done |
| meem-173 | nwamcfg.c'4621-462: nits: s/new/newly/, s/value/a value/, s/current/the current/ | done |
| meem-174 | nwamcfg.c'4659-4770: Duplicate walking logic should be factored out. | factored out |
| meem-175 | nwamcfg.c'4830: Indeed, an error here would be good. | done |
| meem-176 | nwamcfg.c'4839-4852: Essentially duplicates the logic from 1084-1095. | factored out |
| meem-177 | nwamcfg.c'4899-4908: What would go wrong if we attempted to use a file that wasn't a "regular file"? | error |
| meem-178 | nwamcfg.c'4854-4865: Duplicates logic in end_func(). | factored out |
| meem-179 | nwamcfg.c'4918-4925: Duplicates logic in destroy_func(). | factored out |
| meem-180 | nwamcfg.c'4959: Shouldn't cmd_file_mode already be B_FALSE? | done |
SMF (Anurag) [post 1, post 2]
| Reviewer/ID | Comment | Status |
|---|---|---|
| paul-02 | net-loc'265: do_nis(): Keep in mind that the ypservers, if listed by name, need to be in /etc/hosts. NIS looks explicitly there and does not so regular nameservice lookup. Not sure if this is really the place to address it, but there probably should be some warning when the user is doing manual config and uses a hostname. | done |
| paul-03 | net-loc'399: It would probably be good to not use the default nsswitch.nis file. Especially if you have both dns and NIS enabled. In general, one only needs NIS for passwd and automount (and possibly printers). At the very least, it would be good to have hosts and ipnodes list dns first, if available. | done |
| paul-04 | net-nwam:revert_to_legacy_loc() disables IPsec policy and IPfilter policy, changes some properties, then re-enables them. This leaves open a window of opportunity where there is no network security policy, which is a bad thing. Can't you change the config file locations in the SMF properties and do a refresh/restart instead without first disabling? Or refresh/restart/innocuous enable in case the service wasn't started before? | done |
| tony-01 | The integration of 6855845, Allow Property Modification in SMF profiles, into b119 should be sufficient for NWAM phase next to quickly update location specific values and simplify logic in various services and their inter-relationships. | nothing to do |
| tony-02 | Is there a reason why /etc/svc/volatile is used instead of /var/run or a non-persistent pg? | explained, no specific reason |
| tony-03 | ipf, ipf6 files: Comments on line 3 and 16 suggest these files aren't the final version. | done |
| tony-04 | usr/src/cmd/svc/milestone/network-service.xml - No update? However, are dependencies (e.g. NIS dependencies) and comments still accurate if the service is now only responsible for updating DNS information? | undid unnecessary changes |
| tony-05 | network-physical.xml'41,87 - It's not clear from the design spec that there will be additional network/physical instances. Clarification please? | explained, code fixed |
| tony-06 | network-physical.xml'74 - unnecessary diff? | done |
| tony-07 | network-location.xml'100-113 manifest-import is defined as a dependent but the comment states it should be a dependency. Has testing been done to verify correct behavior? | done |
| tony-08 | svc method scripts: These files have similar implementation to figure out whether a service is enabled. It's probably better to have define a single service_is_enabled() in net_include.sh that these three files can consume. | done |
| tony-09 | create/revert_legacy_loc doesn't correctly save/restore custom file. User may have a policy other than custom but has a valid configuration file. The current code doesn't correctly save the configuration file if policy is something other than 'custom' thus can't properly restore it. | |
| tony-10 | net-loc'501 - clearing custom policy_file is probably unnecessary since policy is set to 'none'. | done |
| tony-11 | net-loc'502 - refresh_ipf also needs to be set here to make the changes effective. | done |
| tony-12 | net-loc'stop_svc() - in all uses of this function, no configuration change was made to the target service so a refresh isn't necessary. | done |
| tony-13 | net-loc'refresh_svc() - The name seems incomplete as the function really is refreshing/starting the service with the updated configuration. Perhaps run_svc? | done |