From 589f6ed8ce4b9da11cbdce95d6dcf9ad45792175 Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Mon, 18 Dec 2000 20:03:32 +0000 Subject: [PATCH] Divorce the kernel binary ABI version number from the message format version number. (userland programs should not need to be recompiled when the netgraph kernel internal ABI is changed. Also fix modules that don;t handle the fact that a caller may not supply a return message pointer. (benign at the moment because the calling code checks, but that will change) --- share/man/man4/netgraph.4 | 7 ++-- sys/dev/ar/if_ar.c | 64 +++++++++++++++++------------------ sys/dev/ar/if_ar_isa.c | 64 +++++++++++++++++------------------ sys/dev/lmc/if_lmc.c | 16 +++------ sys/dev/musycc/musycc.c | 58 +++++++++++++++++++------------ sys/dev/sr/if_sr.c | 63 ++++++++++++++++------------------ sys/dev/sr/if_sr_isa.c | 63 ++++++++++++++++------------------ sys/dev/usb/udbp.c | 2 +- sys/i386/isa/if_ar.c | 64 +++++++++++++++++------------------ sys/i386/isa/if_sr.c | 63 ++++++++++++++++------------------ sys/i4b/driver/i4b_ing.c | 2 +- sys/netgraph/netgraph.h | 9 ++++- sys/netgraph/ng_UI.c | 2 +- sys/netgraph/ng_async.c | 2 +- sys/netgraph/ng_base.c | 16 ++++++++- sys/netgraph/ng_bpf.c | 2 +- sys/netgraph/ng_bridge.c | 2 +- sys/netgraph/ng_cisco.c | 2 +- sys/netgraph/ng_echo.c | 2 +- sys/netgraph/ng_ether.c | 2 +- sys/netgraph/ng_frame_relay.c | 2 +- sys/netgraph/ng_hole.c | 2 +- sys/netgraph/ng_iface.c | 2 +- sys/netgraph/ng_ksocket.c | 2 +- sys/netgraph/ng_lmi.c | 27 +++++++++------ sys/netgraph/ng_message.h | 9 +++-- sys/netgraph/ng_mppc.c | 2 +- sys/netgraph/ng_one2many.c | 2 +- sys/netgraph/ng_ppp.c | 2 +- sys/netgraph/ng_pppoe.c | 2 +- sys/netgraph/ng_pptpgre.c | 4 +-- sys/netgraph/ng_rfc1490.c | 2 +- sys/netgraph/ng_sample.c | 2 +- sys/netgraph/ng_socket.c | 2 +- sys/netgraph/ng_tee.c | 2 +- sys/netgraph/ng_tty.c | 2 +- sys/netgraph/ng_vjc.c | 2 +- sys/pci/if_mn.c | 26 +++++++++----- 38 files changed, 318 insertions(+), 281 deletions(-) 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); }