diff --git a/share/man/man4/netgraph.4 b/share/man/man4/netgraph.4 index dd0cbff4ea12..e912b69ae9a7 100644 --- a/share/man/man4/netgraph.4 +++ b/share/man/man4/netgraph.4 @@ -625,7 +625,7 @@ struct ng_cmdlist { }; struct ng_type { - u_int32_t version; /* Must equal NG_VERSION */ + u_int32_t version; /* Must equal NG_ABI_VERSION */ const char *name; /* Unique type name */ /* Module event handler */ @@ -678,7 +678,8 @@ struct ng_mesg { char data[0]; /* Start of cmd/resp data */ }; -#define NG_VERSION 3 /* Netgraph version */ +#define NG_ABI_VERSION 5 /* Netgraph kernel ABI version */ +#define NG_VERSION 4 /* Netgraph message version */ #define NGF_ORIG 0x0000 /* Command */ #define NGF_RESP 0x0001 /* Response */ .Ed @@ -688,7 +689,7 @@ variable length data section which depends on the type cookie and the command. Each field is explained below: .Bl -tag -width xxx .It Dv version -Indicates the version of netgraph itself. The current version is +Indicates the version of the netgraph message protocol itself. The current version is .Dv NG_VERSION . .It Dv arglen This is the length of any extra arguments, which begin at diff --git a/sys/dev/ar/if_ar.c b/sys/dev/ar/if_ar.c index ad5aac9f3ecd..fe9abeba9cb7 100644 --- a/sys/dev/ar/if_ar.c +++ b/sys/dev/ar/if_ar.c @@ -275,7 +275,7 @@ static ng_rcvdata_t ngar_rcvdata; static ng_disconnect_t ngar_disconnect; static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_AR_NODE_TYPE, NULL, ngar_constructor, @@ -2216,66 +2216,64 @@ ngar_newhook(node_p node, hook_p hook, const char *name) * Just respond to the generic TEXT_STATUS message */ static int -ngar_rcvmsg(node_p node, struct ng_mesg *msg, - const char *retaddr, struct ng_mesg **resp, hook_p lasthook) +ngar_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **rptr, hook_p lasthook) { struct ar_softc * sc; + struct ng_mesg *resp = NULL; int error = 0; sc = node->private; switch (msg->header.typecookie) { - case NG_AR_COOKIE: + case NG_AR_COOKIE: error = EINVAL; break; - case NGM_GENERIC_COOKIE: + case NGM_GENERIC_COOKIE: switch(msg->header.cmd) { - case NGM_TEXT_STATUS: { - char *arg; - int pos = 0; - int resplen = sizeof(struct ng_mesg) + 512; - MALLOC(*resp, struct ng_mesg *, resplen, - M_NETGRAPH, M_NOWAIT | M_ZERO); - if (*resp == NULL) { + case NGM_TEXT_STATUS: { + char *arg; + int pos = 0; + + int resplen = sizeof(struct ng_mesg) + 512; + NG_MKRESPONSE(resp, msg, resplen, M_NOWAIT); + if (resp == NULL) { error = ENOMEM; break; - } - arg = (*resp)->data; - - /* - * Put in the throughput information. - */ - pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" + } + arg = (resp)->data; + pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" "highest rate seen: %ld B/S in, %ld B/S out\n", - sc->inbytes, sc->outbytes, - sc->inrate, sc->outrate); - pos += sprintf(arg + pos, + sc->inbytes, sc->outbytes, + sc->inrate, sc->outrate); + pos += sprintf(arg + pos, "%ld output errors\n", sc->oerrors); - pos += sprintf(arg + pos, + pos += sprintf(arg + pos, "ierrors = %ld, %ld, %ld, %ld\n", sc->ierrors[0], sc->ierrors[1], sc->ierrors[2], sc->ierrors[3]); - (*resp)->header.version = NG_VERSION; - (*resp)->header.arglen = strlen(arg) + 1; - (*resp)->header.token = msg->header.token; - (*resp)->header.typecookie = NG_AR_COOKIE; - (*resp)->header.cmd = msg->header.cmd; - strncpy((*resp)->header.cmdstr, "status", - NG_CMDSTRLEN); - } + resp->header.arglen = pos + 1; break; - default: + } + default: error = EINVAL; break; } break; - default: + default: error = EINVAL; break; } + /* Take care of synchronous response, if any */ + if (rptr) + *rptr = resp; + else if (resp) + /* Should send the hard way */ + FREE(resp, M_NETGRAPH); + free(msg, M_NETGRAPH); return (error); } diff --git a/sys/dev/ar/if_ar_isa.c b/sys/dev/ar/if_ar_isa.c index ad5aac9f3ecd..fe9abeba9cb7 100644 --- a/sys/dev/ar/if_ar_isa.c +++ b/sys/dev/ar/if_ar_isa.c @@ -275,7 +275,7 @@ static ng_rcvdata_t ngar_rcvdata; static ng_disconnect_t ngar_disconnect; static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_AR_NODE_TYPE, NULL, ngar_constructor, @@ -2216,66 +2216,64 @@ ngar_newhook(node_p node, hook_p hook, const char *name) * Just respond to the generic TEXT_STATUS message */ static int -ngar_rcvmsg(node_p node, struct ng_mesg *msg, - const char *retaddr, struct ng_mesg **resp, hook_p lasthook) +ngar_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **rptr, hook_p lasthook) { struct ar_softc * sc; + struct ng_mesg *resp = NULL; int error = 0; sc = node->private; switch (msg->header.typecookie) { - case NG_AR_COOKIE: + case NG_AR_COOKIE: error = EINVAL; break; - case NGM_GENERIC_COOKIE: + case NGM_GENERIC_COOKIE: switch(msg->header.cmd) { - case NGM_TEXT_STATUS: { - char *arg; - int pos = 0; - int resplen = sizeof(struct ng_mesg) + 512; - MALLOC(*resp, struct ng_mesg *, resplen, - M_NETGRAPH, M_NOWAIT | M_ZERO); - if (*resp == NULL) { + case NGM_TEXT_STATUS: { + char *arg; + int pos = 0; + + int resplen = sizeof(struct ng_mesg) + 512; + NG_MKRESPONSE(resp, msg, resplen, M_NOWAIT); + if (resp == NULL) { error = ENOMEM; break; - } - arg = (*resp)->data; - - /* - * Put in the throughput information. - */ - pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" + } + arg = (resp)->data; + pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" "highest rate seen: %ld B/S in, %ld B/S out\n", - sc->inbytes, sc->outbytes, - sc->inrate, sc->outrate); - pos += sprintf(arg + pos, + sc->inbytes, sc->outbytes, + sc->inrate, sc->outrate); + pos += sprintf(arg + pos, "%ld output errors\n", sc->oerrors); - pos += sprintf(arg + pos, + pos += sprintf(arg + pos, "ierrors = %ld, %ld, %ld, %ld\n", sc->ierrors[0], sc->ierrors[1], sc->ierrors[2], sc->ierrors[3]); - (*resp)->header.version = NG_VERSION; - (*resp)->header.arglen = strlen(arg) + 1; - (*resp)->header.token = msg->header.token; - (*resp)->header.typecookie = NG_AR_COOKIE; - (*resp)->header.cmd = msg->header.cmd; - strncpy((*resp)->header.cmdstr, "status", - NG_CMDSTRLEN); - } + resp->header.arglen = pos + 1; break; - default: + } + default: error = EINVAL; break; } break; - default: + default: error = EINVAL; break; } + /* Take care of synchronous response, if any */ + if (rptr) + *rptr = resp; + else if (resp) + /* Should send the hard way */ + FREE(resp, M_NETGRAPH); + free(msg, M_NETGRAPH); return (error); } diff --git a/sys/dev/lmc/if_lmc.c b/sys/dev/lmc/if_lmc.c index 3bec1fa8fa6e..0aa6ea633721 100644 --- a/sys/dev/lmc/if_lmc.c +++ b/sys/dev/lmc/if_lmc.c @@ -174,7 +174,7 @@ static const struct ng_cmdlist ng_lmc_cmdlist[] = { }; static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_LMC_NODE_TYPE, NULL, ng_lmc_constructor, @@ -1341,9 +1341,9 @@ ng_lmc_rcvmsg(node_p node, struct ng_mesg *msg, case NGM_TEXT_STATUS: { char *arg; int pos = 0; + int resplen = sizeof(struct ng_mesg) + 512; - MALLOC(resp, struct ng_mesg *, resplen, M_NETGRAPH, - M_NOWAIT | M_ZERO); + NG_MKRESPONSE(resp, msg, resplen, M_NOWAIT); if (resp == NULL) { error = ENOMEM; break; @@ -1363,15 +1363,9 @@ ng_lmc_rcvmsg(node_p node, struct ng_mesg *msg, pos += sprintf(arg + pos, "%ld input errors\n", sc->lmc_ierrors); - resp->header.version = NG_VERSION; - resp->header.arglen = strlen(arg) + 1; - resp->header.token = msg->header.token; - resp->header.typecookie = NG_LMC_COOKIE; - resp->header.cmd = msg->header.cmd; - strncpy(resp->header.cmdstr, "status", - NG_CMDSTRLEN); - } + resp->header.arglen = pos + 1; break; + } default: error = EINVAL; break; diff --git a/sys/dev/musycc/musycc.c b/sys/dev/musycc/musycc.c index c8f35ff30705..85ec6e0415f1 100644 --- a/sys/dev/musycc/musycc.c +++ b/sys/dev/musycc/musycc.c @@ -265,7 +265,7 @@ static ng_rcvdata_t musycc_rcvdata; static ng_disconnect_t musycc_disconnect; static struct ng_type ngtypestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_NODETYPE, NULL, musycc_constructor, @@ -926,56 +926,70 @@ barf: return; } +/* + * Handle status and config enquiries. + * Respond with a synchronous response. + * [JRE] -this would be easier to read with the usual 'switch' structure- + */ static int -musycc_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp, hook_p lasthook) +musycc_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **rptr, hook_p lasthook) { struct softc *sc; + struct ng_mesg *resp = NULL; char *s, *r; + int error = 0; sc = node->private; + if (rptr) + *rptr = NULL; /* default answer in case of errors */ if (msg->header.typecookie != NGM_GENERIC_COOKIE) goto out; if (msg->header.cmd == NGM_TEXT_STATUS) { - NG_MKRESPONSE(*resp, msg, + NG_MKRESPONSE(resp, msg, sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT); - if (*resp == NULL) { - FREE(msg, M_NETGRAPH); - return (ENOMEM); + if (resp == NULL) { + error = ENOMEM; + goto out; } - s = (char *)(*resp)->data; + s = (char *)resp->data; status_8370(sc, s); - (*resp)->header.arglen = strlen(s) + 1; + resp->header.arglen = strlen(s) + 1; FREE(msg, M_NETGRAPH); - return (0); - } - if (msg->header.cmd == NGM_TEXT_CONFIG) { + + } else if (msg->header.cmd == NGM_TEXT_CONFIG) { if (msg->header.arglen) { s = (char *)msg->data; } else { s = NULL; } - NG_MKRESPONSE(*resp, msg, + NG_MKRESPONSE(resp, msg, sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT); - if (*resp == NULL) { - FREE(msg, M_NETGRAPH); - return (ENOMEM); + if (resp == NULL) { + error = ENOMEM; + goto out; } - r = (char *)(*resp)->data; + r = (char *)resp->data; *r = '\0'; musycc_config(node, s, r); - (*resp)->header.arglen = strlen(r) + 1; + resp->header.arglen = strlen(r) + 1; FREE(msg, M_NETGRAPH); - return (0); - } + } else { + error = EINVAL; + } out: - if (resp) - *resp = NULL; + /* Take care of synchronous response, if any */ + if (rptr) + *rptr = resp; + else if (resp) + FREE(resp, M_NETGRAPH); /* eventually 'send' the response */ + FREE(msg, M_NETGRAPH); - return (EINVAL); + return (error); } static int diff --git a/sys/dev/sr/if_sr.c b/sys/dev/sr/if_sr.c index 78acfdd26b58..9ca41d47f22a 100644 --- a/sys/dev/sr/if_sr.c +++ b/sys/dev/sr/if_sr.c @@ -375,7 +375,7 @@ static ng_rcvdata_t ngsr_rcvdata; static ng_disconnect_t ngsr_disconnect; static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_SR_NODE_TYPE, NULL, ngsr_constructor, @@ -3170,41 +3170,38 @@ ngsr_newhook(node_p node, hook_p hook, const char *name) */ static int ngsr_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **resp, hook_p lasthook) + struct ng_mesg **rptr, hook_p lasthook) { struct sr_softc * sc; + struct ng_mesg *resp = NULL; int error = 0; sc = node->private; switch (msg->header.typecookie) { - case NG_SR_COOKIE: + case NG_SR_COOKIE: error = EINVAL; break; - case NGM_GENERIC_COOKIE: + case NGM_GENERIC_COOKIE: switch(msg->header.cmd) { - case NGM_TEXT_STATUS: { - char *arg; - int pos = 0; - int resplen = sizeof(struct ng_mesg) + 512; - MALLOC(*resp, struct ng_mesg *, resplen, - M_NETGRAPH, M_NOWAIT | M_ZERO); - if (*resp == NULL) { + case NGM_TEXT_STATUS: { + char *arg; + int pos = 0; + + int resplen = sizeof(struct ng_mesg) + 512; + NG_MKRESPONSE(resp, msg, resplen, M_NOWAIT); + if (resp == NULL) { error = ENOMEM; break; - } - arg = (*resp)->data; - - /* - * Put in the throughput information. - */ - pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" + } + arg = (resp)->data; + pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" "highest rate seen: %ld B/S in, %ld B/S out\n", - sc->inbytes, sc->outbytes, - sc->inrate, sc->outrate); - pos += sprintf(arg + pos, + sc->inbytes, sc->outbytes, + sc->inrate, sc->outrate); + pos += sprintf(arg + pos, "%ld output errors\n", sc->oerrors); - pos += sprintf(arg + pos, + pos += sprintf(arg + pos, "ierrors = %ld, %ld, %ld, %ld, %ld, %ld\n", sc->ierrors[0], sc->ierrors[1], @@ -3213,24 +3210,24 @@ ngsr_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, sc->ierrors[4], sc->ierrors[5]); - (*resp)->header.version = NG_VERSION; - (*resp)->header.arglen = strlen(arg) + 1; - (*resp)->header.token = msg->header.token; - (*resp)->header.typecookie = NG_SR_COOKIE; - (*resp)->header.cmd = msg->header.cmd; - strncpy((*resp)->header.cmdstr, "status", - NG_CMDSTRLEN); - } + resp->header.arglen = pos + 1; break; - default: + } + default: error = EINVAL; break; - } + } break; - default: + default: error = EINVAL; break; } + /* Take care of synchronous response, if any */ + if (rptr) + *rptr = resp; + else if (resp) + FREE(resp, M_NETGRAPH); + free(msg, M_NETGRAPH); return (error); } diff --git a/sys/dev/sr/if_sr_isa.c b/sys/dev/sr/if_sr_isa.c index 78acfdd26b58..9ca41d47f22a 100644 --- a/sys/dev/sr/if_sr_isa.c +++ b/sys/dev/sr/if_sr_isa.c @@ -375,7 +375,7 @@ static ng_rcvdata_t ngsr_rcvdata; static ng_disconnect_t ngsr_disconnect; static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_SR_NODE_TYPE, NULL, ngsr_constructor, @@ -3170,41 +3170,38 @@ ngsr_newhook(node_p node, hook_p hook, const char *name) */ static int ngsr_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **resp, hook_p lasthook) + struct ng_mesg **rptr, hook_p lasthook) { struct sr_softc * sc; + struct ng_mesg *resp = NULL; int error = 0; sc = node->private; switch (msg->header.typecookie) { - case NG_SR_COOKIE: + case NG_SR_COOKIE: error = EINVAL; break; - case NGM_GENERIC_COOKIE: + case NGM_GENERIC_COOKIE: switch(msg->header.cmd) { - case NGM_TEXT_STATUS: { - char *arg; - int pos = 0; - int resplen = sizeof(struct ng_mesg) + 512; - MALLOC(*resp, struct ng_mesg *, resplen, - M_NETGRAPH, M_NOWAIT | M_ZERO); - if (*resp == NULL) { + case NGM_TEXT_STATUS: { + char *arg; + int pos = 0; + + int resplen = sizeof(struct ng_mesg) + 512; + NG_MKRESPONSE(resp, msg, resplen, M_NOWAIT); + if (resp == NULL) { error = ENOMEM; break; - } - arg = (*resp)->data; - - /* - * Put in the throughput information. - */ - pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" + } + arg = (resp)->data; + pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" "highest rate seen: %ld B/S in, %ld B/S out\n", - sc->inbytes, sc->outbytes, - sc->inrate, sc->outrate); - pos += sprintf(arg + pos, + sc->inbytes, sc->outbytes, + sc->inrate, sc->outrate); + pos += sprintf(arg + pos, "%ld output errors\n", sc->oerrors); - pos += sprintf(arg + pos, + pos += sprintf(arg + pos, "ierrors = %ld, %ld, %ld, %ld, %ld, %ld\n", sc->ierrors[0], sc->ierrors[1], @@ -3213,24 +3210,24 @@ ngsr_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, sc->ierrors[4], sc->ierrors[5]); - (*resp)->header.version = NG_VERSION; - (*resp)->header.arglen = strlen(arg) + 1; - (*resp)->header.token = msg->header.token; - (*resp)->header.typecookie = NG_SR_COOKIE; - (*resp)->header.cmd = msg->header.cmd; - strncpy((*resp)->header.cmdstr, "status", - NG_CMDSTRLEN); - } + resp->header.arglen = pos + 1; break; - default: + } + default: error = EINVAL; break; - } + } break; - default: + default: error = EINVAL; break; } + /* Take care of synchronous response, if any */ + if (rptr) + *rptr = resp; + else if (resp) + FREE(resp, M_NETGRAPH); + free(msg, M_NETGRAPH); return (error); } diff --git a/sys/dev/usb/udbp.c b/sys/dev/usb/udbp.c index 906f5242566f..29e203ece5d0 100644 --- a/sys/dev/usb/udbp.c +++ b/sys/dev/usb/udbp.c @@ -185,7 +185,7 @@ Static const struct ng_cmdlist ng_udbp_cmdlist[] = { /* Netgraph node type descriptor */ Static struct ng_type ng_udbp_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_UDBP_NODE_TYPE, NULL, ng_udbp_constructor, diff --git a/sys/i386/isa/if_ar.c b/sys/i386/isa/if_ar.c index ad5aac9f3ecd..fe9abeba9cb7 100644 --- a/sys/i386/isa/if_ar.c +++ b/sys/i386/isa/if_ar.c @@ -275,7 +275,7 @@ static ng_rcvdata_t ngar_rcvdata; static ng_disconnect_t ngar_disconnect; static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_AR_NODE_TYPE, NULL, ngar_constructor, @@ -2216,66 +2216,64 @@ ngar_newhook(node_p node, hook_p hook, const char *name) * Just respond to the generic TEXT_STATUS message */ static int -ngar_rcvmsg(node_p node, struct ng_mesg *msg, - const char *retaddr, struct ng_mesg **resp, hook_p lasthook) +ngar_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **rptr, hook_p lasthook) { struct ar_softc * sc; + struct ng_mesg *resp = NULL; int error = 0; sc = node->private; switch (msg->header.typecookie) { - case NG_AR_COOKIE: + case NG_AR_COOKIE: error = EINVAL; break; - case NGM_GENERIC_COOKIE: + case NGM_GENERIC_COOKIE: switch(msg->header.cmd) { - case NGM_TEXT_STATUS: { - char *arg; - int pos = 0; - int resplen = sizeof(struct ng_mesg) + 512; - MALLOC(*resp, struct ng_mesg *, resplen, - M_NETGRAPH, M_NOWAIT | M_ZERO); - if (*resp == NULL) { + case NGM_TEXT_STATUS: { + char *arg; + int pos = 0; + + int resplen = sizeof(struct ng_mesg) + 512; + NG_MKRESPONSE(resp, msg, resplen, M_NOWAIT); + if (resp == NULL) { error = ENOMEM; break; - } - arg = (*resp)->data; - - /* - * Put in the throughput information. - */ - pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" + } + arg = (resp)->data; + pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" "highest rate seen: %ld B/S in, %ld B/S out\n", - sc->inbytes, sc->outbytes, - sc->inrate, sc->outrate); - pos += sprintf(arg + pos, + sc->inbytes, sc->outbytes, + sc->inrate, sc->outrate); + pos += sprintf(arg + pos, "%ld output errors\n", sc->oerrors); - pos += sprintf(arg + pos, + pos += sprintf(arg + pos, "ierrors = %ld, %ld, %ld, %ld\n", sc->ierrors[0], sc->ierrors[1], sc->ierrors[2], sc->ierrors[3]); - (*resp)->header.version = NG_VERSION; - (*resp)->header.arglen = strlen(arg) + 1; - (*resp)->header.token = msg->header.token; - (*resp)->header.typecookie = NG_AR_COOKIE; - (*resp)->header.cmd = msg->header.cmd; - strncpy((*resp)->header.cmdstr, "status", - NG_CMDSTRLEN); - } + resp->header.arglen = pos + 1; break; - default: + } + default: error = EINVAL; break; } break; - default: + default: error = EINVAL; break; } + /* Take care of synchronous response, if any */ + if (rptr) + *rptr = resp; + else if (resp) + /* Should send the hard way */ + FREE(resp, M_NETGRAPH); + free(msg, M_NETGRAPH); return (error); } diff --git a/sys/i386/isa/if_sr.c b/sys/i386/isa/if_sr.c index 78acfdd26b58..9ca41d47f22a 100644 --- a/sys/i386/isa/if_sr.c +++ b/sys/i386/isa/if_sr.c @@ -375,7 +375,7 @@ static ng_rcvdata_t ngsr_rcvdata; static ng_disconnect_t ngsr_disconnect; static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_SR_NODE_TYPE, NULL, ngsr_constructor, @@ -3170,41 +3170,38 @@ ngsr_newhook(node_p node, hook_p hook, const char *name) */ static int ngsr_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **resp, hook_p lasthook) + struct ng_mesg **rptr, hook_p lasthook) { struct sr_softc * sc; + struct ng_mesg *resp = NULL; int error = 0; sc = node->private; switch (msg->header.typecookie) { - case NG_SR_COOKIE: + case NG_SR_COOKIE: error = EINVAL; break; - case NGM_GENERIC_COOKIE: + case NGM_GENERIC_COOKIE: switch(msg->header.cmd) { - case NGM_TEXT_STATUS: { - char *arg; - int pos = 0; - int resplen = sizeof(struct ng_mesg) + 512; - MALLOC(*resp, struct ng_mesg *, resplen, - M_NETGRAPH, M_NOWAIT | M_ZERO); - if (*resp == NULL) { + case NGM_TEXT_STATUS: { + char *arg; + int pos = 0; + + int resplen = sizeof(struct ng_mesg) + 512; + NG_MKRESPONSE(resp, msg, resplen, M_NOWAIT); + if (resp == NULL) { error = ENOMEM; break; - } - arg = (*resp)->data; - - /* - * Put in the throughput information. - */ - pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" + } + arg = (resp)->data; + pos = sprintf(arg, "%ld bytes in, %ld bytes out\n" "highest rate seen: %ld B/S in, %ld B/S out\n", - sc->inbytes, sc->outbytes, - sc->inrate, sc->outrate); - pos += sprintf(arg + pos, + sc->inbytes, sc->outbytes, + sc->inrate, sc->outrate); + pos += sprintf(arg + pos, "%ld output errors\n", sc->oerrors); - pos += sprintf(arg + pos, + pos += sprintf(arg + pos, "ierrors = %ld, %ld, %ld, %ld, %ld, %ld\n", sc->ierrors[0], sc->ierrors[1], @@ -3213,24 +3210,24 @@ ngsr_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, sc->ierrors[4], sc->ierrors[5]); - (*resp)->header.version = NG_VERSION; - (*resp)->header.arglen = strlen(arg) + 1; - (*resp)->header.token = msg->header.token; - (*resp)->header.typecookie = NG_SR_COOKIE; - (*resp)->header.cmd = msg->header.cmd; - strncpy((*resp)->header.cmdstr, "status", - NG_CMDSTRLEN); - } + resp->header.arglen = pos + 1; break; - default: + } + default: error = EINVAL; break; - } + } break; - default: + default: error = EINVAL; break; } + /* Take care of synchronous response, if any */ + if (rptr) + *rptr = resp; + else if (resp) + FREE(resp, M_NETGRAPH); + free(msg, M_NETGRAPH); return (error); } diff --git a/sys/i4b/driver/i4b_ing.c b/sys/i4b/driver/i4b_ing.c index c55e43b89423..8807fceebb00 100644 --- a/sys/i4b/driver/i4b_ing.c +++ b/sys/i4b/driver/i4b_ing.c @@ -203,7 +203,7 @@ static const struct ng_cmdlist ng_ing_cmdlist[] = { /* Netgraph node type descriptor */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_ING_NODE_TYPE, NULL, ng_ing_constructor, diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h index 48fb4f57ccd7..56cf7d6f3f6b 100644 --- a/sys/netgraph/netgraph.h +++ b/sys/netgraph/netgraph.h @@ -172,7 +172,7 @@ struct ng_cmdlist { */ struct ng_type { - u_int32_t version; /* must equal NG_VERSION */ + u_int32_t version; /* must equal NG_API_VERSION */ const char *name; /* Unique type name */ modeventhand_t mod_event; /* Module event handler (optional) */ ng_constructor_t *constructor; /* Node constructor */ @@ -191,6 +191,13 @@ struct ng_type { int refs; /* number of instances */ }; +/* + * This defines the in-kernel binary interface version. + * It is possible to change this but leave the external message + * API the same. Each type also has it's own cookies for versioning as well. + */ +#define NG_ABI_VERSION 5 + /* Send data packet with meta-data */ #define NG_SEND_DATA(err, hook, m, meta) \ do { \ diff --git a/sys/netgraph/ng_UI.c b/sys/netgraph/ng_UI.c index 9d490b9b7697..0e2ef10492c8 100644 --- a/sys/netgraph/ng_UI.c +++ b/sys/netgraph/ng_UI.c @@ -77,7 +77,7 @@ static ng_disconnect_t ng_UI_disconnect; /* Node type descriptor */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_UI_NODE_TYPE, NULL, ng_UI_constructor, diff --git a/sys/netgraph/ng_async.c b/sys/netgraph/ng_async.c index 8dc951a1f040..cbc51bb70504 100644 --- a/sys/netgraph/ng_async.c +++ b/sys/netgraph/ng_async.c @@ -148,7 +148,7 @@ static const struct ng_cmdlist nga_cmdlist[] = { /* Define the netgraph node type */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_ASYNC_NODE_TYPE, NULL, nga_constructor, diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index 981d0bf7a926..d9b26f4b89a6 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -856,7 +856,9 @@ ng_newtype(struct ng_type *tp) const size_t namelen = strlen(tp->name); /* Check version and type name fields */ - if (tp->version != NG_VERSION || namelen == 0 || namelen > NG_TYPELEN) { + if ((tp->version != NG_ABI_VERSION) + || (namelen == 0) + || (namelen > NG_TYPELEN)) { TRAP_ERROR; return (EINVAL); } @@ -1489,6 +1491,12 @@ ng_generic_msg(node_p here, struct ng_mesg *msg, const char *retaddr, break; } + /* Check response pointer */ + if (resp == NULL) { + error = EINVAL; + break; + } + /* Get a response message with lots of room */ NG_MKRESPONSE(rp, msg, sizeof(*ascii) + bufSize, M_NOWAIT); if (rp == NULL) { @@ -1565,6 +1573,12 @@ ng_generic_msg(node_p here, struct ng_mesg *msg, const char *retaddr, } ascii->data[ascii->header.arglen - 1] = '\0'; + /* Check response pointer */ + if (resp == NULL) { + error = EINVAL; + break; + } + /* Get a response message with lots of room */ NG_MKRESPONSE(rp, msg, sizeof(*binary) + bufSize, M_NOWAIT); if (rp == NULL) { diff --git a/sys/netgraph/ng_bpf.c b/sys/netgraph/ng_bpf.c index 49cc3e779970..6d1955066649 100644 --- a/sys/netgraph/ng_bpf.c +++ b/sys/netgraph/ng_bpf.c @@ -186,7 +186,7 @@ static const struct ng_cmdlist ng_bpf_cmdlist[] = { /* Netgraph type descriptor */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_BPF_NODE_TYPE, NULL, ng_bpf_constructor, diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c index 68a4c0c15880..59ba0cce5c8d 100644 --- a/sys/netgraph/ng_bridge.c +++ b/sys/netgraph/ng_bridge.c @@ -266,7 +266,7 @@ static const struct ng_cmdlist ng_bridge_cmdlist[] = { /* Node type descriptor */ static struct ng_type ng_bridge_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_BRIDGE_NODE_TYPE, NULL, ng_bridge_constructor, diff --git a/sys/netgraph/ng_cisco.c b/sys/netgraph/ng_cisco.c index 76316c4b30b3..539e684800e9 100644 --- a/sys/netgraph/ng_cisco.c +++ b/sys/netgraph/ng_cisco.c @@ -171,7 +171,7 @@ static const struct ng_cmdlist ng_cisco_cmdlist[] = { /* Node type */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_CISCO_NODE_TYPE, NULL, cisco_constructor, diff --git a/sys/netgraph/ng_echo.c b/sys/netgraph/ng_echo.c index 8ef95a427bd8..6c46341e2740 100644 --- a/sys/netgraph/ng_echo.c +++ b/sys/netgraph/ng_echo.c @@ -61,7 +61,7 @@ static ng_disconnect_t nge_disconnect; /* Netgraph type */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_ECHO_NODE_TYPE, NULL, NULL, diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index 806798a7f8ee..194b5eebcdbb 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -180,7 +180,7 @@ static const struct ng_cmdlist ng_ether_cmdlist[] = { }; static struct ng_type ng_ether_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_ETHER_NODE_TYPE, ng_ether_mod_event, ng_ether_constructor, diff --git a/sys/netgraph/ng_frame_relay.c b/sys/netgraph/ng_frame_relay.c index 830800beb2ca..96d56bfe977c 100644 --- a/sys/netgraph/ng_frame_relay.c +++ b/sys/netgraph/ng_frame_relay.c @@ -137,7 +137,7 @@ static int ngfrm_allocate_CTX(sc_p sc, int dlci); /* Netgraph type */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_FRAMERELAY_NODE_TYPE, NULL, ngfrm_constructor, diff --git a/sys/netgraph/ng_hole.c b/sys/netgraph/ng_hole.c index 43ed1f2fb33d..1da47b69fbc7 100644 --- a/sys/netgraph/ng_hole.c +++ b/sys/netgraph/ng_hole.c @@ -57,7 +57,7 @@ static ng_rcvdata_t ngh_rcvdata; static ng_disconnect_t ngh_disconnect; static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_HOLE_NODE_TYPE, NULL, NULL, diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index 992d9b9e3a61..3df564ac18a5 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -181,7 +181,7 @@ static const struct ng_cmdlist ng_iface_cmds[] = { /* Node type descriptor */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_IFACE_NODE_TYPE, NULL, ng_iface_constructor, diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c index c01f679a5ca5..9898da9ad5bc 100644 --- a/sys/netgraph/ng_ksocket.c +++ b/sys/netgraph/ng_ksocket.c @@ -459,7 +459,7 @@ static const struct ng_cmdlist ng_ksocket_cmds[] = { /* Node type descriptor */ static struct ng_type ng_ksocket_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_KSOCKET_NODE_TYPE, NULL, ng_ksocket_constructor, diff --git a/sys/netgraph/ng_lmi.c b/sys/netgraph/ng_lmi.c index 70194643621c..9bede7182f72 100644 --- a/sys/netgraph/ng_lmi.c +++ b/sys/netgraph/ng_lmi.c @@ -98,7 +98,7 @@ static ng_disconnect_t nglmi_disconnect; static int nglmi_checkdata(hook_p hook, struct mbuf *m, meta_p meta); static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_LMI_NODE_TYPE, NULL, nglmi_constructor, @@ -450,10 +450,11 @@ ngauto_state_machine(sc_p sc) */ static int nglmi_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, - struct ng_mesg **resp, hook_p lasthook) + struct ng_mesg **rptr, hook_p lasthook) { - int error = 0; sc_p sc = node->private; + struct ng_mesg *resp = NULL; + int error = 0; switch (msg->header.typecookie) { case NGM_GENERIC_COOKIE: @@ -463,12 +464,12 @@ nglmi_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, char *arg; int pos, count; - NG_MKRESPONSE(*resp, msg, NG_TEXTRESPONSE, M_NOWAIT); - if (*resp == NULL) { + NG_MKRESPONSE(resp, msg, NG_TEXTRESPONSE, M_NOWAIT); + if (resp == NULL) { error = ENOMEM; break; } - arg = (*resp)->data; + arg = resp->data; pos = sprintf(arg, "protocol %s ", sc->protoname); if (sc->flags & SCF_FIXED) pos += sprintf(arg + pos, "fixed\n"); @@ -494,7 +495,7 @@ nglmi_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, == DLCI_UP) ? "up" : "down"); } } - (*resp)->header.arglen = pos + 1; + resp->header.arglen = pos + 1; break; } default: @@ -509,12 +510,12 @@ nglmi_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct nglmistat *stat; int k; - NG_MKRESPONSE(*resp, msg, sizeof(*stat), M_NOWAIT); - if (!*resp) { + NG_MKRESPONSE(resp, msg, sizeof(*stat), M_NOWAIT); + if (!resp) { error = ENOMEM; break; } - stat = (struct nglmistat *) (*resp)->data; + stat = (struct nglmistat *) resp->data; strncpy(stat->proto, sc->protoname, sizeof(stat->proto) - 1); strncpy(stat->hook, @@ -542,6 +543,12 @@ nglmi_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, error = EINVAL; break; } + + if (rptr) + *rptr = resp; + else if (resp != NULL) + FREE(resp, M_NETGRAPH); + FREE(msg, M_NETGRAPH); return (error); } diff --git a/sys/netgraph/ng_message.h b/sys/netgraph/ng_message.h index 3eb6096cc1b8..993768d82ef7 100644 --- a/sys/netgraph/ng_message.h +++ b/sys/netgraph/ng_message.h @@ -54,7 +54,7 @@ /* A netgraph message */ struct ng_mesg { struct ng_msghdr { - u_char version; /* must == NG_VERSION */ + u_char version; /* == NGM_VERSION */ u_char spare; /* pad to 2 bytes */ u_int16_t arglen; /* length of data */ u_int32_t flags; /* message status */ @@ -66,6 +66,7 @@ struct ng_mesg { char data[0]; /* placeholder for actual data */ }; + /* Keep this in sync with the above structure definition */ #define NG_GENERIC_NG_MESG_INFO(dtype) { \ { \ @@ -82,7 +83,11 @@ struct ng_mesg { } \ } -/* Negraph type binary compatibility field */ +/* + * Netgraph message header compatibility field + * Interfaces within the kernel are defined by a different + * value (see NG_ABI_VERSION in netgraph.g) + */ #define NG_VERSION 4 /* Flags field flags */ diff --git a/sys/netgraph/ng_mppc.c b/sys/netgraph/ng_mppc.c index 6c84cda4cec2..d9c5a3196ce7 100644 --- a/sys/netgraph/ng_mppc.c +++ b/sys/netgraph/ng_mppc.c @@ -143,7 +143,7 @@ static void ng_mppc_reset_req(node_p node); /* Node type descriptor */ static struct ng_type ng_mppc_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_MPPC_NODE_TYPE, NULL, ng_mppc_constructor, diff --git a/sys/netgraph/ng_one2many.c b/sys/netgraph/ng_one2many.c index 96f93c9b644f..ad0f90fb079f 100644 --- a/sys/netgraph/ng_one2many.c +++ b/sys/netgraph/ng_one2many.c @@ -162,7 +162,7 @@ static const struct ng_cmdlist ng_one2many_cmdlist[] = { /* Node type descriptor */ static struct ng_type ng_one2many_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_ONE2MANY_NODE_TYPE, NULL, ng_one2many_constructor, diff --git a/sys/netgraph/ng_ppp.c b/sys/netgraph/ng_ppp.c index 88caa6309f6a..a2fea533a1ea 100644 --- a/sys/netgraph/ng_ppp.c +++ b/sys/netgraph/ng_ppp.c @@ -342,7 +342,7 @@ static const struct ng_cmdlist ng_ppp_cmds[] = { /* Node type descriptor */ static struct ng_type ng_ppp_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_PPP_NODE_TYPE, NULL, ng_ppp_constructor, diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c index af82ac057543..14bf6501a1a9 100644 --- a/sys/netgraph/ng_pppoe.c +++ b/sys/netgraph/ng_pppoe.c @@ -148,7 +148,7 @@ static const struct ng_cmdlist ng_pppoe_cmds[] = { /* Netgraph node type descriptor */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_PPPOE_NODE_TYPE, NULL, ng_pppoe_constructor, diff --git a/sys/netgraph/ng_pptpgre.c b/sys/netgraph/ng_pptpgre.c index 7d4fedfc1e5b..c5306b0b33c7 100644 --- a/sys/netgraph/ng_pptpgre.c +++ b/sys/netgraph/ng_pptpgre.c @@ -245,7 +245,7 @@ static const struct ng_cmdlist ng_pptpgre_cmdlist[] = { /* Node type descriptor */ static struct ng_type ng_pptpgre_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_PPTPGRE_NODE_TYPE, NULL, ng_pptpgre_constructor, @@ -378,12 +378,12 @@ ng_pptpgre_rcvmsg(node_p node, struct ng_mesg *msg, error = EINVAL; break; } +done: if (rptr) *rptr = resp; else if (resp) FREE(resp, M_NETGRAPH); -done: FREE(msg, M_NETGRAPH); return (error); } diff --git a/sys/netgraph/ng_rfc1490.c b/sys/netgraph/ng_rfc1490.c index 0eb090f5f737..b31fdcaf5c9e 100644 --- a/sys/netgraph/ng_rfc1490.c +++ b/sys/netgraph/ng_rfc1490.c @@ -96,7 +96,7 @@ static ng_disconnect_t ng_rfc1490_disconnect; /* Node type descriptor */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_RFC1490_NODE_TYPE, NULL, ng_rfc1490_constructor, diff --git a/sys/netgraph/ng_sample.c b/sys/netgraph/ng_sample.c index 4d4bfbaa6148..831e07047b4a 100644 --- a/sys/netgraph/ng_sample.c +++ b/sys/netgraph/ng_sample.c @@ -96,7 +96,7 @@ static const struct ng_cmdlist ng_xxx_cmdlist[] = { /* Netgraph node type descriptor */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_XXX_NODE_TYPE, NULL, ng_xxx_constructor, diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index 7608ababf2bc..19ea5e087030 100644 --- a/sys/netgraph/ng_socket.c +++ b/sys/netgraph/ng_socket.c @@ -120,7 +120,7 @@ static int ship_msg(struct ngpcb *pcbp, struct ng_mesg *msg, /* Netgraph type descriptor */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_SOCKET_NODE_TYPE, ngs_mod_event, ngs_constructor, diff --git a/sys/netgraph/ng_tee.c b/sys/netgraph/ng_tee.c index be6111a5ffd5..89ae12ef440f 100644 --- a/sys/netgraph/ng_tee.c +++ b/sys/netgraph/ng_tee.c @@ -128,7 +128,7 @@ static const struct ng_cmdlist ng_tee_cmds[] = { /* Netgraph type descriptor */ static struct ng_type ng_tee_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_TEE_NODE_TYPE, NULL, ngt_constructor, diff --git a/sys/netgraph/ng_tty.c b/sys/netgraph/ng_tty.c index 6236d6ed72cb..54ad7d5b5954 100644 --- a/sys/netgraph/ng_tty.c +++ b/sys/netgraph/ng_tty.c @@ -159,7 +159,7 @@ static struct linesw ngt_disc = { /* Netgraph node type descriptor */ static struct ng_type typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_TTY_NODE_TYPE, ngt_mod_event, ngt_constructor, diff --git a/sys/netgraph/ng_vjc.c b/sys/netgraph/ng_vjc.c index 41a16d616329..60da6b230e3a 100644 --- a/sys/netgraph/ng_vjc.c +++ b/sys/netgraph/ng_vjc.c @@ -222,7 +222,7 @@ static const struct ng_cmdlist ng_vjc_cmds[] = { /* Node type descriptor */ static struct ng_type ng_vjc_typestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_VJC_NODE_TYPE, NULL, ng_vjc_constructor, diff --git a/sys/pci/if_mn.c b/sys/pci/if_mn.c index 43ac4891f517..8028389c2159 100644 --- a/sys/pci/if_mn.c +++ b/sys/pci/if_mn.c @@ -187,7 +187,7 @@ static ng_rcvdata_t ngmn_rcvdata; static ng_disconnect_t ngmn_disconnect; static struct ng_type mntypestruct = { - NG_VERSION, + NG_ABI_VERSION, NG_MN_NODE_TYPE, NULL, ngmn_constructor, @@ -281,9 +281,11 @@ ngmn_shutdown(node_p nodep) } static int -ngmn_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp, hook_p lasthook) +ngmn_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, + struct ng_mesg **rptr, hook_p lasthook) { struct softc *sc; + struct ng_mesg *resp = NULL; struct schan *sch; char *arg; int pos, i; @@ -291,19 +293,20 @@ ngmn_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct ng_mes sc = node->private; if (msg->header.typecookie != NGM_GENERIC_COOKIE || + rptr == NULL || /* temporary */ msg->header.cmd != NGM_TEXT_STATUS) { - if (resp) - *resp = NULL; + if (rptr) + *rptr = NULL; FREE(msg, M_NETGRAPH); return (EINVAL); } - NG_MKRESPONSE(*resp, msg, sizeof(struct ng_mesg) + NG_TEXTRESPONSE, + NG_MKRESPONSE(resp, msg, sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT); - if (*resp == NULL) { + if (resp == NULL) { FREE(msg, M_NETGRAPH); return (ENOMEM); } - arg = (char *)(*resp)->data; + arg = (char *)resp->data; pos = 0; pos += sprintf(pos + arg,"Framer status %b;\n", sc->framer_state, "\20" "\40LOS\37AIS\36LFA\35RRA" @@ -371,7 +374,14 @@ ngmn_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct ng_mes pos += sprintf(arg + pos, " Xmit bytes pending %ld\n", sch->tx_pending); } - (*resp)->header.arglen = pos + 1; + resp->header.arglen = pos + 1; + + /* Take care of synchronous response, if any */ + if (rptr) + *rptr = resp; + else if (resp) + FREE(resp, M_NETGRAPH); /* Will eventually send the hard way */ + FREE(msg, M_NETGRAPH); return (0); }