diff options
author | Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> | 2021-07-22 17:22:19 +0200 |
---|---|---|
committer | Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> | 2021-09-03 21:14:57 +0200 |
commit | 80d556f9fa4f5a4857a6619909d286fb17e240f7 (patch) | |
tree | 1cf2159782852efa874056c7792228fd805ff8a1 | |
parent | 8fe4436b2642718e9aa922b01d40ce7f01603cfc (diff) | |
download | illumos-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.c | 75 | ||||
-rw-r--r-- | usr/src/lib/libipmp/common/ipmp_mpathd.c | 20 | ||||
-rw-r--r-- | usr/src/lib/libipmp/common/ipmp_mpathd.h | 17 | ||||
-rw-r--r-- | usr/src/lib/libipmp/common/ipmp_query.c | 186 | ||||
-rw-r--r-- | usr/src/lib/libipmp/common/ipmp_query.h | 49 | ||||
-rw-r--r-- | usr/src/lib/libipmp/common/ipmp_query_impl.h | 8 |
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; /* |