summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Rosenfeld <rosenfeld@grumpf.hope-2000.org>2021-07-22 17:22:19 +0200
committerHans Rosenfeld <rosenfeld@grumpf.hope-2000.org>2021-09-03 21:14:57 +0200
commit80d556f9fa4f5a4857a6619909d286fb17e240f7 (patch)
tree1cf2159782852efa874056c7792228fd805ff8a1
parent8fe4436b2642718e9aa922b01d40ce7f01603cfc (diff)
downloadillumos-joyent-80d556f9fa4f5a4857a6619909d286fb17e240f7.tar.gz
13995 libipmp <--> in.mpathd communication not 64bit safe
Reviewed by: Robert Mustacchi <rm+illumos@fingolfin.org> Reviewed by: Gordon Ross <Gordon.W.Ross@gmail.com> Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c75
-rw-r--r--usr/src/lib/libipmp/common/ipmp_mpathd.c20
-rw-r--r--usr/src/lib/libipmp/common/ipmp_mpathd.h17
-rw-r--r--usr/src/lib/libipmp/common/ipmp_query.c186
-rw-r--r--usr/src/lib/libipmp/common/ipmp_query.h49
-rw-r--r--usr/src/lib/libipmp/common/ipmp_query_impl.h8
6 files changed, 299 insertions, 56 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c
index dbae74bbab..3064428a36 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c
+++ b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
*/
#include "mpd_defs.h"
@@ -582,7 +584,7 @@ select_test_ifs(void)
struct phyint_instance *pii;
struct phyint_instance *next_pii;
struct logint *li;
- struct logint *probe_logint;
+ struct logint *probe_logint;
boolean_t target_scan_reqd = _B_FALSE;
int rating;
@@ -793,7 +795,7 @@ static void
check_testconfig(void)
{
struct phyint *pi;
- struct logint *li;
+ struct logint *li;
char abuf[INET6_ADDRSTRLEN];
int pri;
@@ -2524,11 +2526,12 @@ process_query(int fd, mi_query_t *miq)
if (retval != IPMP_SUCCESS)
goto out;
- retval = ipmp_writetlv(fd, IPMP_SNAP, sizeof (*snap), snap);
+ retval = send_grouplist(fd, snap->sn_grlistp);
if (retval != IPMP_SUCCESS)
goto out;
- retval = send_grouplist(fd, snap->sn_grlistp);
+ retval = ipmp_writetlv(fd, IPMP_IFCNT, sizeof (uint32_t),
+ &snap->sn_nif);
if (retval != IPMP_SUCCESS)
goto out;
@@ -2539,6 +2542,11 @@ process_query(int fd, mi_query_t *miq)
goto out;
}
+ retval = ipmp_writetlv(fd, IPMP_GROUPCNT, sizeof (uint32_t),
+ &snap->sn_ngroup);
+ if (retval != IPMP_SUCCESS)
+ goto out;
+
grlp = snap->sn_grinfolistp;
for (; grlp != NULL; grlp = grlp->grl_next) {
retval = send_groupinfo(fd, grlp->grl_grinfop);
@@ -2546,6 +2554,11 @@ process_query(int fd, mi_query_t *miq)
goto out;
}
+ retval = ipmp_writetlv(fd, IPMP_ADDRCNT, sizeof (uint32_t),
+ &snap->sn_naddr);
+ if (retval != IPMP_SUCCESS)
+ goto out;
+
adlp = snap->sn_adinfolistp;
for (; adlp != NULL; adlp = adlp->adl_next) {
retval = send_addrinfo(fd, adlp->adl_adinfop);
@@ -2572,9 +2585,32 @@ send_groupinfo(int fd, ipmp_groupinfo_t *grinfop)
{
ipmp_iflist_t *iflistp = grinfop->gr_iflistp;
ipmp_addrlist_t *adlistp = grinfop->gr_adlistp;
+ ipmp_groupinfo_xfer_t grxfer;
unsigned int retval;
- retval = ipmp_writetlv(fd, IPMP_GROUPINFO, sizeof (*grinfop), grinfop);
+ /*
+ * We can't directly transfer an ipmp_groupinfo_t due to the embedded
+ * pointers to ipmp_iflist_t and ipmp_addr_list_t. Copy the data over
+ * to a temporary transfer structure that doesn't have these embedded
+ * pointers.
+ */
+ memset(&grxfer, 0, sizeof (grxfer));
+
+ grxfer.grx_sig = grinfop->gr_sig;
+ grxfer.grx_state = grinfop->gr_state;
+ grxfer.grx_fdt = grinfop->gr_fdt;
+
+ memcpy(grxfer.grx_name, grinfop->gr_name, sizeof (grxfer.grx_name));
+ memcpy(grxfer.grx_ifname, grinfop->gr_ifname,
+ sizeof (grxfer.grx_ifname));
+ memcpy(grxfer.grx_m4ifname, grinfop->gr_m4ifname,
+ sizeof (grxfer.grx_m4ifname));
+ memcpy(grxfer.grx_m6ifname, grinfop->gr_m6ifname,
+ sizeof (grxfer.grx_m6ifname));
+ memcpy(grxfer.grx_bcifname, grinfop->gr_bcifname,
+ sizeof (grxfer.grx_bcifname));
+
+ retval = ipmp_writetlv(fd, IPMP_GROUPINFO, sizeof (grxfer), &grxfer);
if (retval != IPMP_SUCCESS)
return (retval);
@@ -2596,9 +2632,35 @@ send_ifinfo(int fd, ipmp_ifinfo_t *ifinfop)
{
ipmp_addrlist_t *adlist4p = ifinfop->if_targinfo4.it_targlistp;
ipmp_addrlist_t *adlist6p = ifinfop->if_targinfo6.it_targlistp;
+ ipmp_ifinfo_xfer_t ifxfer;
unsigned int retval;
- retval = ipmp_writetlv(fd, IPMP_IFINFO, sizeof (*ifinfop), ifinfop);
+ /*
+ * We can't directly tranfer an ipmp_ifinfo_t due to the embedded
+ * ipmp_addrlist_t pointer in if_targinfo_t. Copy the data over to
+ * a temporary transfer structure that doesn't have that embedded
+ * pointer.
+ */
+ memset(&ifxfer, 0, sizeof (ifxfer));
+
+ ifxfer.ifx_state = ifinfop->if_state;
+ ifxfer.ifx_type = ifinfop->if_type;
+ ifxfer.ifx_linkstate = ifinfop->if_linkstate;
+ ifxfer.ifx_probestate = ifinfop->if_probestate;
+ ifxfer.ifx_flags = ifinfop->if_flags;
+ ifxfer.ifx_targinfo4.itx_testaddr = ifinfop->if_targinfo4.it_testaddr;
+ ifxfer.ifx_targinfo4.itx_targmode = ifinfop->if_targinfo4.it_targmode;
+ ifxfer.ifx_targinfo6.itx_testaddr = ifinfop->if_targinfo6.it_testaddr;
+ ifxfer.ifx_targinfo6.itx_targmode = ifinfop->if_targinfo6.it_targmode;
+
+ memcpy(ifxfer.ifx_name, ifinfop->if_name, sizeof (ifxfer.ifx_name));
+ memcpy(ifxfer.ifx_group, ifinfop->if_group, sizeof (ifxfer.ifx_group));
+ memcpy(ifxfer.ifx_targinfo4.itx_name, ifinfop->if_targinfo4.it_name,
+ sizeof (ifxfer.ifx_targinfo4.itx_name));
+ memcpy(ifxfer.ifx_targinfo6.itx_name, ifinfop->if_targinfo6.it_name,
+ sizeof (ifxfer.ifx_targinfo6.itx_name));
+
+ retval = ipmp_writetlv(fd, IPMP_IFINFO, sizeof (ifxfer), &ifxfer);
if (retval != IPMP_SUCCESS)
return (retval);
@@ -2701,7 +2763,6 @@ daemonize(void)
*/
static int
closefunc(void *not_used, int fd)
-/* ARGSUSED */
{
if (fd != lsock_v4 && fd != lsock_v6)
(void) close(fd);
diff --git a/usr/src/lib/libipmp/common/ipmp_mpathd.c b/usr/src/lib/libipmp/common/ipmp_mpathd.c
index e24de71017..80a7e579a1 100644
--- a/usr/src/lib/libipmp/common/ipmp_mpathd.c
+++ b/usr/src/lib/libipmp/common/ipmp_mpathd.c
@@ -20,6 +20,8 @@
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
*/
/*
@@ -40,6 +42,7 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/types.h>
+#include <sys/isa_defs.h>
#include "ipmp.h"
#include "ipmp_mpathd.h"
@@ -123,15 +126,18 @@ ipmp_readtlv(int fd, ipmp_infotype_t *typep, size_t *lenp, void **valuep,
{
int retval;
void *value;
+ uint32_t tlen;
retval = ipmp_read(fd, typep, sizeof (*typep), endtp);
if (retval != IPMP_SUCCESS)
return (retval);
- retval = ipmp_read(fd, lenp, sizeof (*lenp), endtp);
+ retval = ipmp_read(fd, &tlen, sizeof (tlen), endtp);
if (retval != IPMP_SUCCESS)
return (retval);
+ *lenp = tlen;
+
value = malloc(*lenp);
if (value == NULL) {
/*
@@ -187,16 +193,24 @@ int
ipmp_writetlv(int fd, ipmp_infotype_t type, size_t len, void *value)
{
int retval;
+ uint32_t tlen;
+
+#if defined(_LP64)
+ if (len > UINT32_MAX)
+ return (IPMP_EPROTO);
+#endif
+
+ tlen = (uint32_t)len;
retval = ipmp_write(fd, &type, sizeof (type));
if (retval != IPMP_SUCCESS)
return (retval);
- retval = ipmp_write(fd, &len, sizeof (len));
+ retval = ipmp_write(fd, &tlen, sizeof (uint32_t));
if (retval != IPMP_SUCCESS)
return (retval);
- return (ipmp_write(fd, value, len));
+ return (ipmp_write(fd, value, tlen));
}
/*
diff --git a/usr/src/lib/libipmp/common/ipmp_mpathd.h b/usr/src/lib/libipmp/common/ipmp_mpathd.h
index 7df3b4fd92..eec34c7f33 100644
--- a/usr/src/lib/libipmp/common/ipmp_mpathd.h
+++ b/usr/src/lib/libipmp/common/ipmp_mpathd.h
@@ -20,6 +20,8 @@
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
*/
#ifndef _IPMP_MPATHD_H
@@ -59,11 +61,14 @@ enum {
typedef enum {
IPMP_GROUPLIST = 1,
IPMP_GROUPINFO = 2,
- IPMP_IFINFO = 3,
- IPMP_IFLIST = 4,
- IPMP_SNAP = 5,
- IPMP_ADDRLIST = 6,
- IPMP_ADDRINFO = 7
+ IPMP_GROUPCNT = 3,
+ IPMP_IFINFO = 4,
+ IPMP_IFLIST = 5,
+ IPMP_IFCNT = 6,
+ IPMP_ADDRLIST = 7,
+ IPMP_ADDRINFO = 8,
+ IPMP_ADDRCNT = 9,
+ IPMP_SNAP = 10
} ipmp_infotype_t;
/*
@@ -79,7 +84,7 @@ typedef struct mi_ping {
* offline that must exist for the operation to succeed.
*/
typedef struct mi_offline {
- uint32_t mio_command;
+ uint32_t mio_command;
char mio_ifname[LIFNAMSIZ];
uint32_t mio_min_redundancy;
} mi_offline_t;
diff --git a/usr/src/lib/libipmp/common/ipmp_query.c b/usr/src/lib/libipmp/common/ipmp_query.c
index a0af2da578..f3c05491f6 100644
--- a/usr/src/lib/libipmp/common/ipmp_query.c
+++ b/usr/src/lib/libipmp/common/ipmp_query.c
@@ -20,6 +20,8 @@
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
*/
/*
@@ -250,6 +252,37 @@ ipmp_freegrouplist(ipmp_grouplist_t *grlistp)
}
/*
+ * Convert a ipmp_groupinfo_xfer_t used for communication with in.mpathd
+ * into a newly allocated ipmp_groupinfo_t. Free the ipmp_groupinfo_xfer_t,
+ * regardless of failure.
+ */
+static ipmp_groupinfo_t *
+ipmp_convertgroupinfo(ipmp_groupinfo_xfer_t *grxferp)
+{
+ ipmp_groupinfo_t *grinfop;
+
+ grinfop = calloc(1, sizeof (ipmp_groupinfo_t));
+ if (grinfop != NULL) {
+ memcpy(grinfop->gr_name, grxferp->grx_name,
+ sizeof (grinfop->gr_name));
+ grinfop->gr_sig = grxferp->grx_sig;
+ grinfop->gr_state = grxferp->grx_state;
+ memcpy(grinfop->gr_ifname, grxferp->grx_ifname,
+ sizeof (grinfop->gr_ifname));
+ memcpy(grinfop->gr_m4ifname, grxferp->grx_m4ifname,
+ sizeof (grinfop->gr_m4ifname));
+ memcpy(grinfop->gr_m6ifname, grxferp->grx_m6ifname,
+ sizeof (grinfop->gr_m6ifname));
+ memcpy(grinfop->gr_bcifname, grxferp->grx_bcifname,
+ sizeof (grinfop->gr_bcifname));
+ grinfop->gr_fdt = grxferp->grx_fdt;
+ }
+
+ free(grxferp);
+
+ return (grinfop);
+}
+/*
* Using `handle', get the group information associated with group `name' and
* store the results in a dynamically allocated buffer pointed to by
* `*grinfopp'. Returns an IPMP error code.
@@ -262,6 +295,7 @@ ipmp_getgroupinfo(ipmp_handle_t handle, const char *name,
int retval;
struct timeval end;
ipmp_groupinfo_t *grinfop;
+ ipmp_groupinfo_xfer_t *grxferp;
if (statep->st_snap != NULL) {
grinfop = ipmp_snap_getgroupinfo(statep->st_snap, name);
@@ -276,10 +310,14 @@ ipmp_getgroupinfo(ipmp_handle_t handle, const char *name,
if (retval != IPMP_SUCCESS)
return (retval);
- retval = ipmp_readinfo(statep, IPMP_GROUPINFO, (void **)grinfopp, &end);
+ retval = ipmp_readinfo(statep, IPMP_GROUPINFO, (void **)&grxferp, &end);
if (retval != IPMP_SUCCESS)
return (ipmp_querydone(statep, retval));
+ *grinfopp = ipmp_convertgroupinfo(grxferp);
+ if (*grinfopp == NULL)
+ return (ipmp_querydone(statep, IPMP_ENOMEM));
+
retval = ipmp_readgroupinfo_lists(statep, *grinfopp, &end);
if (retval != IPMP_SUCCESS)
free(*grinfopp);
@@ -299,6 +337,48 @@ ipmp_freegroupinfo(ipmp_groupinfo_t *grinfop)
}
/*
+ * Convert a ipmp_ifinfo_xfer_t used for communication with in.mpathd
+ * into a newly allocated ipmp_ifinfo_t. Free the ipmp_ifinfo_xfer_t,
+ * regardless of failure.
+ */
+static ipmp_ifinfo_t *
+ipmp_convertifinfo(ipmp_ifinfo_xfer_t *ifxferp)
+{
+ ipmp_ifinfo_t *ifinfop;
+
+ ifinfop = calloc(1, sizeof (ipmp_ifinfo_t));
+ if (ifinfop != NULL) {
+ memcpy(ifinfop->if_name, ifxferp->ifx_name,
+ sizeof (ifinfop->if_name));
+ memcpy(ifinfop->if_group, ifxferp->ifx_group,
+ sizeof (ifinfop->if_group));
+ ifinfop->if_state = ifxferp->ifx_state;
+ ifinfop->if_type = ifxferp->ifx_type;
+ ifinfop->if_linkstate = ifxferp->ifx_linkstate;
+ ifinfop->if_probestate = ifxferp->ifx_probestate;
+ ifinfop->if_flags = ifxferp->ifx_flags;
+ memcpy(ifinfop->if_targinfo4.it_name,
+ ifxferp->ifx_targinfo4.itx_name,
+ sizeof (ifinfop->if_targinfo4.it_name));
+ ifinfop->if_targinfo4.it_testaddr =
+ ifxferp->ifx_targinfo4.itx_testaddr;
+ ifinfop->if_targinfo4.it_targmode =
+ ifxferp->ifx_targinfo4.itx_targmode;
+ memcpy(ifinfop->if_targinfo6.it_name,
+ ifxferp->ifx_targinfo6.itx_name,
+ sizeof (ifinfop->if_targinfo6.it_name));
+ ifinfop->if_targinfo6.it_testaddr =
+ ifxferp->ifx_targinfo6.itx_testaddr;
+ ifinfop->if_targinfo6.it_targmode =
+ ifxferp->ifx_targinfo6.itx_targmode;
+ }
+
+ free(ifxferp);
+
+ return (ifinfop);
+}
+
+/*
* Using `handle', get the interface information associated with interface
* `name' and store the results in a dynamically allocated buffer pointed to
* by `*ifinfopp'. Returns an IPMP error code.
@@ -308,6 +388,7 @@ ipmp_getifinfo(ipmp_handle_t handle, const char *name, ipmp_ifinfo_t **ifinfopp)
{
ipmp_state_t *statep = handle;
ipmp_ifinfo_t *ifinfop;
+ ipmp_ifinfo_xfer_t *ifxferp;
int retval;
struct timeval end;
@@ -324,10 +405,14 @@ ipmp_getifinfo(ipmp_handle_t handle, const char *name, ipmp_ifinfo_t **ifinfopp)
if (retval != IPMP_SUCCESS)
return (retval);
- retval = ipmp_readinfo(statep, IPMP_IFINFO, (void **)ifinfopp, &end);
+ retval = ipmp_readinfo(statep, IPMP_IFINFO, (void **)&ifxferp, &end);
if (retval != IPMP_SUCCESS)
return (ipmp_querydone(statep, retval));
+ *ifinfopp = ipmp_convertifinfo(ifxferp);
+ if (*ifinfopp == NULL)
+ return (ipmp_querydone(statep, IPMP_ENOMEM));
+
retval = ipmp_readifinfo_lists(statep, *ifinfopp, &end);
if (retval != IPMP_SUCCESS)
free(*ifinfopp);
@@ -407,9 +492,9 @@ static boolean_t
ipmp_checktlv(ipmp_infotype_t type, size_t len, void *value)
{
ipmp_iflist_t *iflistp;
- ipmp_ifinfo_t *ifinfop;
+ ipmp_ifinfo_xfer_t *ifxferp;
ipmp_grouplist_t *grlistp;
- ipmp_groupinfo_t *grinfop;
+ ipmp_groupinfo_xfer_t *grxferp;
ipmp_addrlist_t *adlistp;
unsigned int i;
@@ -438,12 +523,12 @@ ipmp_checktlv(ipmp_infotype_t type, size_t len, void *value)
break;
case IPMP_IFINFO:
- ifinfop = (ipmp_ifinfo_t *)value;
- if (len != sizeof (ipmp_ifinfo_t))
+ ifxferp = (ipmp_ifinfo_xfer_t *)value;
+ if (len != sizeof (ipmp_ifinfo_xfer_t))
return (B_FALSE);
- if (!hasnulbyte(ifinfop->if_name, LIFNAMSIZ) ||
- !hasnulbyte(ifinfop->if_group, LIFGRNAMSIZ))
+ if (!hasnulbyte(ifxferp->ifx_name, LIFNAMSIZ) ||
+ !hasnulbyte(ifxferp->ifx_group, LIFGRNAMSIZ))
return (B_FALSE);
break;
@@ -459,16 +544,18 @@ ipmp_checktlv(ipmp_infotype_t type, size_t len, void *value)
break;
case IPMP_GROUPINFO:
- grinfop = (ipmp_groupinfo_t *)value;
- if (len != sizeof (ipmp_groupinfo_t))
+ grxferp = (ipmp_groupinfo_xfer_t *)value;
+ if (len != sizeof (ipmp_groupinfo_xfer_t))
return (B_FALSE);
- if (!hasnulbyte(grinfop->gr_name, LIFGRNAMSIZ))
+ if (!hasnulbyte(grxferp->grx_name, LIFGRNAMSIZ))
return (B_FALSE);
break;
- case IPMP_SNAP:
- if (len != sizeof (ipmp_snap_t))
+ case IPMP_ADDRCNT:
+ case IPMP_GROUPCNT:
+ case IPMP_IFCNT:
+ if (len != sizeof (uint32_t))
return (B_FALSE);
break;
@@ -995,13 +1082,16 @@ ipmp_snap_getaddrinfo(ipmp_snap_t *snap, const char *grname,
static int
ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
{
- ipmp_snap_t *snap, *osnap;
+ uint64_t naddr, ngroup, nif;
+ ipmp_snap_t *snap;
ipmp_infotype_t type;
int retval;
size_t len;
void *infop;
struct timeval end;
+ naddr = ngroup = nif = UINT64_MAX;
+
snap = ipmp_snap_create();
if (snap == NULL)
return (IPMP_ENOMEM);
@@ -1012,18 +1102,12 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
return (retval);
}
- retval = ipmp_readinfo(statep, IPMP_SNAP, (void **)&osnap, &end);
- if (retval != IPMP_SUCCESS) {
- ipmp_snap_free(snap);
- return (ipmp_querydone(statep, retval));
- }
-
/*
- * Using the information in the `osnap' snapshot, build up our own
- * snapshot. We know there will always be at least one TLV (for
- * IPMP_GROUPLIST). If we receive anything illogical (e.g., more than
- * the expected number of interfaces), then bail out. However, to a
- * large extent we have to trust the information sent by in.mpathd.
+ * Build up our snapshot. We know there will always be at least four
+ * TLVs for IPMP_GROUPLIST, IPMP_IFCNT, IPMP_GROUPCNT, and IPMP_ADDRCNT.
+ * If we receive anything illogical (e.g., more than the expected number
+ * of interfaces), then bail out. However, to a large extent we have to
+ * trust the information sent by in.mpathd.
*/
do {
infop = NULL;
@@ -1046,11 +1130,17 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
break;
case IPMP_IFINFO:
- if (snap->sn_nif == osnap->sn_nif) {
+ if (snap->sn_nif == nif) {
retval = IPMP_EPROTO;
break;
}
+ infop = ipmp_convertifinfo(infop);
+ if (infop == NULL) {
+ retval = IPMP_ENOMEM;
+ break;
+ }
+
/*
* Read in V4 and V6 targlist TLVs that follow.
*/
@@ -1066,7 +1156,7 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
break;
case IPMP_ADDRINFO:
- if (snap->sn_naddr == osnap->sn_naddr) {
+ if (snap->sn_naddr == naddr) {
retval = IPMP_EPROTO;
break;
}
@@ -1079,11 +1169,17 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
break;
case IPMP_GROUPINFO:
- if (snap->sn_ngroup == osnap->sn_ngroup) {
+ if (snap->sn_ngroup == ngroup) {
retval = IPMP_EPROTO;
break;
}
+ infop = ipmp_convertgroupinfo(infop);
+ if (infop == NULL) {
+ retval = IPMP_ENOMEM;
+ break;
+ }
+
/*
* Read in IPMP groupinfo list TLVs that follow.
*/
@@ -1098,6 +1194,33 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
}
break;
+ case IPMP_ADDRCNT:
+ if (naddr != UINT64_MAX) {
+ retval = IPMP_EPROTO;
+ break;
+ }
+
+ naddr = *(uint32_t *)infop;
+ break;
+
+ case IPMP_GROUPCNT:
+ if (ngroup != UINT64_MAX) {
+ retval = IPMP_EPROTO;
+ break;
+ }
+
+ ngroup = *(uint32_t *)infop;
+ break;
+
+ case IPMP_IFCNT:
+ if (nif != UINT64_MAX) {
+ retval = IPMP_EPROTO;
+ break;
+ }
+
+ nif = *(uint32_t *)infop;
+ break;
+
default:
retval = IPMP_EPROTO;
break;
@@ -1105,15 +1228,12 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
fail:
if (retval != IPMP_SUCCESS) {
free(infop);
- free(osnap);
ipmp_snap_free(snap);
return (ipmp_querydone(statep, retval));
}
- } while (snap->sn_grlistp == NULL || snap->sn_nif < osnap->sn_nif ||
- snap->sn_ngroup < osnap->sn_ngroup ||
- snap->sn_naddr < osnap->sn_naddr);
+ } while (snap->sn_grlistp == NULL || snap->sn_nif < nif ||
+ snap->sn_ngroup < ngroup || snap->sn_naddr < naddr);
- free(osnap);
*snapp = snap;
return (ipmp_querydone(statep, IPMP_SUCCESS));
}
diff --git a/usr/src/lib/libipmp/common/ipmp_query.h b/usr/src/lib/libipmp/common/ipmp_query.h
index 160f561dd2..f2482163f3 100644
--- a/usr/src/lib/libipmp/common/ipmp_query.h
+++ b/usr/src/lib/libipmp/common/ipmp_query.h
@@ -20,6 +20,8 @@
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
*/
#ifndef _IPMP_QUERY_H
@@ -60,7 +62,7 @@ typedef enum ipmp_if_linkstate {
typedef enum ipmp_if_flags {
IPMP_IFFLAG_INACTIVE = 0x1,
IPMP_IFFLAG_HWADDRDUP = 0x2,
- IPMP_IFFLAG_ACTIVE = 0x4,
+ IPMP_IFFLAG_ACTIVE = 0x4,
IPMP_IFFLAG_DOWN = 0x8
} ipmp_if_flags_t;
@@ -84,6 +86,7 @@ typedef enum ipmp_if_targmode {
typedef struct ipmp_grouplist {
uint64_t gl_sig;
unsigned int gl_ngroup;
+ uint32_t gl_pad;
char gl_groups[1][LIFGRNAMSIZ];
} ipmp_grouplist_t;
@@ -106,6 +109,7 @@ typedef struct ipmp_iflist {
*/
typedef struct ipmp_addrlist {
unsigned int al_naddr;
+ uint32_t al_pad;
struct sockaddr_storage al_addrs[1];
} ipmp_addrlist_t;
@@ -113,7 +117,8 @@ typedef struct ipmp_addrlist {
IPMP_LIST_SIZE(addrlist, sizeof (struct sockaddr_storage), naddr)
/*
- * Data type describing the state of an IPMP group.
+ * Data type describing the state of an IPMP group, and a subset data type
+ * used for communication between libipmp and in.mpathd.
*/
typedef struct ipmp_groupinfo {
char gr_name[LIFGRNAMSIZ];
@@ -128,8 +133,20 @@ typedef struct ipmp_groupinfo {
unsigned int gr_fdt;
} ipmp_groupinfo_t;
+typedef struct ipmp_groupinfo_xfer {
+ char grx_name[LIFGRNAMSIZ];
+ uint64_t grx_sig;
+ ipmp_group_state_t grx_state;
+ char grx_ifname[LIFNAMSIZ];
+ char grx_m4ifname[LIFNAMSIZ];
+ char grx_m6ifname[LIFNAMSIZ];
+ char grx_bcifname[LIFNAMSIZ];
+ unsigned int grx_fdt;
+} ipmp_groupinfo_xfer_t;
+
/*
- * Data type describing IPMP target information for a particular interface.
+ * Data type describing IPMP target information for a particular interface,
+ * and a subset data type used for communication between libipmp and in.mpathd.
*/
typedef struct ipmp_targinfo {
char it_name[LIFNAMSIZ];
@@ -138,8 +155,17 @@ typedef struct ipmp_targinfo {
ipmp_addrlist_t *it_targlistp;
} ipmp_targinfo_t;
+typedef struct ipmp_targinfo_xfer {
+ char itx_name[LIFNAMSIZ];
+ struct sockaddr_storage itx_testaddr;
+ ipmp_if_targmode_t itx_targmode;
+ uint32_t itx_pad;
+} ipmp_targinfo_xfer_t;
+
+
/*
- * Data type describing the IPMP-related state of an interface.
+ * Data type describing the IPMP-related state of an interface, and a subset
+ * data type used for communication between libipmp and in.mpathd.
*/
typedef struct ipmp_ifinfo {
char if_name[LIFNAMSIZ];
@@ -153,6 +179,20 @@ typedef struct ipmp_ifinfo {
ipmp_targinfo_t if_targinfo6;
} ipmp_ifinfo_t;
+typedef struct ipmp_ifinfo_xfer {
+ char ifx_name[LIFNAMSIZ];
+ char ifx_group[LIFGRNAMSIZ];
+ ipmp_if_state_t ifx_state;
+ ipmp_if_type_t ifx_type;
+ ipmp_if_linkstate_t ifx_linkstate;
+ ipmp_if_probestate_t ifx_probestate;
+ ipmp_if_flags_t ifx_flags;
+ uint32_t ifx_pad;
+ ipmp_targinfo_xfer_t ifx_targinfo4;
+ ipmp_targinfo_xfer_t ifx_targinfo6;
+} ipmp_ifinfo_xfer_t;
+
+
/*
* Data type describing an IPMP data address.
*/
@@ -161,6 +201,7 @@ typedef struct ipmp_addrinfo {
ipmp_addr_state_t ad_state;
char ad_group[LIFGRNAMSIZ];
char ad_binding[LIFNAMSIZ];
+ uint32_t ad_pad;
} ipmp_addrinfo_t;
typedef enum {
diff --git a/usr/src/lib/libipmp/common/ipmp_query_impl.h b/usr/src/lib/libipmp/common/ipmp_query_impl.h
index 6ac5c3ca27..221e5a838f 100644
--- a/usr/src/lib/libipmp/common/ipmp_query_impl.h
+++ b/usr/src/lib/libipmp/common/ipmp_query_impl.h
@@ -20,6 +20,8 @@
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
*/
#ifndef _IPMP_QUERY_IMPL_H
@@ -69,9 +71,9 @@ typedef struct ipmp_snap {
ipmp_groupinfolist_t *sn_grinfolistp;
ipmp_ifinfolist_t *sn_ifinfolistp;
ipmp_addrinfolist_t *sn_adinfolistp;
- unsigned int sn_ngroup;
- unsigned int sn_nif;
- unsigned int sn_naddr;
+ uint32_t sn_ngroup;
+ uint32_t sn_nif;
+ uint32_t sn_naddr;
} ipmp_snap_t;
/*