void bridge_status(void) { struct ifreq ifr; struct ifbrparam bp1, bp2; if (!is_bridge(name)) return; strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) return; bridge_cfg("\t"); bridge_list("\t"); if (aflag && !ifaliases) return; strlcpy(bp1.ifbrp_name, name, sizeof(bp1.ifbrp_name)); if (ioctl(s, SIOCBRDGGCACHE, (caddr_t)&bp1) < 0) return; strlcpy(bp2.ifbrp_name, name, sizeof(bp2.ifbrp_name)); if (ioctl(s, SIOCBRDGGTO, (caddr_t)&bp2) < 0) return; printf("\tAddresses (max cache: %u, timeout: %u):\n", bp1.ifbrp_csize, bp2.ifbrp_ctime); bridge_addrs("\t\t", 0); }
void conf_brcfg(FILE *output, int ifs, struct if_nameindex *ifn_list, char *ifname) { struct if_nameindex *br_ifnp; char tmp_str[TMPSIZ]; long l_tmp; if ((l_tmp = bridge_cfg(ifs, ifname, PRIORITY)) != -1 && l_tmp != DEFAULT_PRIORITY) fprintf(output, " priority %lu\n", l_tmp); if ((l_tmp = bridge_cfg(ifs, ifname, HELLOTIME)) != -1 && l_tmp != DEFAULT_HELLOTIME) fprintf(output, " hellotime %lu\n", l_tmp); if ((l_tmp = bridge_cfg(ifs, ifname, FWDDELAY)) != -1 && l_tmp != DEFAULT_FWDDELAY) fprintf(output, " fwddelay %lu\n", l_tmp); if ((l_tmp = bridge_cfg(ifs, ifname, MAXAGE)) != -1 && l_tmp != DEFAULT_MAXAGE) fprintf(output, " maxage %lu\n", l_tmp); if ((l_tmp = bridge_cfg(ifs, ifname, MAXADDR)) != -1 && l_tmp != DEFAULT_MAXADDR) fprintf(output, " maxaddr %lu\n", l_tmp); if ((l_tmp = bridge_cfg(ifs, ifname, TIMEOUT)) != -1 && l_tmp != DEFAULT_TIMEOUT) fprintf(output, " timeout %lu\n", l_tmp); if (bridge_list(ifs, ifname, NULL, tmp_str, TMPSIZ, MEMBER)) fprintf(output, " member %s\n", tmp_str); if (bridge_list(ifs, ifname, NULL, tmp_str, TMPSIZ, STP)) fprintf(output, " stp %s\n", tmp_str); if (bridge_list(ifs, ifname, NULL, tmp_str, TMPSIZ, SPAN)) fprintf(output, " span %s\n", tmp_str); if (bridge_list(ifs, ifname, NULL, tmp_str, TMPSIZ, NOLEARNING)) fprintf(output, " no learning %s\n", tmp_str); if (bridge_list(ifs, ifname, NULL, tmp_str, TMPSIZ, NODISCOVER)) fprintf(output, " no discover %s\n", tmp_str); if (bridge_list(ifs, ifname, NULL, tmp_str, TMPSIZ, BLOCKNONIP)) fprintf(output, " blocknonip %s\n", tmp_str); if (bridge_list(ifs, ifname, " ", tmp_str, TMPSIZ, CONF_IFPRIORITY)) fprintf(output, "%s", tmp_str); if (bridge_list(ifs, ifname, " ", tmp_str, TMPSIZ, CONF_IFCOST)) fprintf(output, "%s", tmp_str); bridge_confaddrs(ifs, ifname, " static ", output); for (br_ifnp = ifn_list; br_ifnp->if_name != NULL; br_ifnp++) /* try all interface names for member rules */ bridge_rules(ifs, ifname, br_ifnp->if_name, " rule ", output); }
int show_int(int argc, char **argv) { struct ifaddrs *ifap, *ifa; struct if_nameindex *ifn_list, *ifnp; struct ifreq ifr, ifrdesc; struct if_data if_data; struct sockaddr_in sin, sin2, sin3; struct timeval tv; struct vlanreq vreq; short tmp; int ifs, br, flags, days, hours, mins, pntd; int ippntd = 0; time_t c; char *type, *lladdr, *ifname = NULL; const char *carp; char tmp_str[512], tmp_str2[512], ifdescr[IFDESCRSIZE]; if (argc == 3) ifname = argv[2]; /* * Show all interfaces when no ifname specified. */ if (ifname == NULL) { if ((ifn_list = if_nameindex()) == NULL) { printf("%% show_int: if_nameindex failed\n"); return 1; } for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { char *args[] = { NULL, NULL, ifnp->if_name }; show_int(3, args); } if_freenameindex(ifn_list); return(0); } else if (!is_valid_ifname(ifname)) { printf("%% interface %s not found\n", ifname); return(1); } if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("%% show_int: %s\n", strerror(errno)); return(1); } if (!(br = is_bridge(ifs, (char *)ifname))) br = 0; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); /* * Show up/down status and last change time */ flags = get_ifflags(ifname, ifs); ifr.ifr_data = (caddr_t)&if_data; if (ioctl(ifs, SIOCGIFDATA, (caddr_t)&ifr) < 0) { printf("%% show_int: SIOCGIFDATA: %s\n", strerror(errno)); close(ifs); return(1); } printf("%% %s", ifname); /* description */ memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, ifname, sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = (caddr_t)&ifdescr; if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 && strlen(ifrdesc.ifr_data)) printf(" (%s)", ifrdesc.ifr_data); putchar('\n'); printf(" %s is %s", br ? "Bridge" : "Interface", flags & IFF_UP ? "up" : "down"); if (if_lastchange.tv_sec) { gettimeofday(&tv, (struct timezone *)0); c = difftime(tv.tv_sec, if_lastchange.tv_sec); days = c / SECSPERDAY; c %= SECSPERDAY; hours = c / SECSPERHOUR; c %= SECSPERHOUR; mins = c / SECSPERMIN; c %= SECSPERMIN; printf(" (last change "); if (days) printf("%id ", days); printf("%02i:%02i:%02i)", hours, mins, c); } printf(", protocol is %s", flags & IFF_RUNNING ? "up" : "down"); printf("\n"); type = iftype(if_type); printf(" Interface type %s", type); if (flags & IFF_BROADCAST) printf(" (Broadcast)"); else if (flags & IFF_POINTOPOINT) printf(" (PointToPoint)"); if ((lladdr = get_hwdaddr(ifname)) != NULL) printf(", hardware address %s", lladdr); printf("\n"); media_status(ifs, ifname, " Media type "); /* * Print interface IP address, and broadcast or * destination if available. But, don't print broadcast * if it is what we would expect given the ip and netmask! */ if (getifaddrs(&ifap) != 0) { printf("%% show_int: getifaddrs failed: %s\n", strerror(errno)); return(1); } /* * Cycle through getifaddrs for interfaces with our * desired name that sport AF_INET, print the IP and * related information. */ for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ)) continue; if (ifa->ifa_addr->sa_family != AF_INET) continue; memcpy(&sin, ifa->ifa_addr, sizeof(struct sockaddr_in)); memcpy(&sin2, ifa->ifa_netmask, sizeof(struct sockaddr_in)); if (sin.sin_addr.s_addr == 0 || sin2.sin_addr.s_addr == 0) continue; if (!ippntd) printf(" Internet address"); printf("%s %s", ippntd ? "," : "", netname4(sin.sin_addr.s_addr, &sin2)); ippntd = 1; if (flags & IFF_POINTOPOINT) { memcpy(&sin3, ifa->ifa_dstaddr, sizeof(struct sockaddr_in)); printf(" (Destination %s)", inet_ntoa(sin3.sin_addr)); } else if (flags & IFF_BROADCAST) { memcpy(&sin3, ifa->ifa_broadaddr, sizeof(struct sockaddr_in)); /* * no reason to show the broadcast addr * if it is standard (this should always * be true unless someone has messed up their * network or they are playing around...) */ if (ntohl(sin3.sin_addr.s_addr) != in4_brdaddr(sin.sin_addr.s_addr, sin2.sin_addr.s_addr)) printf(" (Broadcast %s)", inet_ntoa(sin3.sin_addr)); } } if (ippntd) { ippntd = 0; printf("\n"); } freeifaddrs(ifap); if (!br) { if (phys_status(ifs, ifname, tmp_str, tmp_str2, sizeof(tmp_str), sizeof(tmp_str2)) > 0) printf(" Tunnel source %s destination %s\n", tmp_str, tmp_str2); if ((carp = carp_state(ifs, ifname)) != NULL) printf(" CARP state %s\n", carp); /* * Display MTU, line rate, and ALTQ token rate info * (if available) */ printf(" MTU %u bytes", if_mtu); if (if_baudrate) printf(", Line Rate %qu %s\n", MBPS(if_baudrate) ? MBPS(if_baudrate) : if_baudrate / 1000, MBPS(if_baudrate) ? "Mbps" : "Kbps"); else printf("\n"); memset(&vreq, 0, sizeof(struct vlanreq)); ifr.ifr_data = (caddr_t)&vreq; if (ioctl(ifs, SIOCGETVLAN, (caddr_t)&ifr) != -1) if(vreq.vlr_tag || (vreq.vlr_parent[0] != '\0')) printf(" 802.1Q vlan tag %d, parent %s\n", vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ? "<none>" : vreq.vlr_parent); } if (get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWID) != NULL) { printf(" SSID %s", tmp_str); if(get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWKEY) != NULL) printf(", key %s", tmp_str); if ((tmp = get_nwinfo(ifname, tmp_str, sizeof(tmp_str), POWERSAVE) != NULL)) printf(", powersaving (%s ms)\n", tmp_str); printf("\n"); } /* * Display remaining info from if_data structure */ printf(" %qu packets input, %qu bytes, %qu errors, %qu drops\n", if_ipackets, if_ibytes, if_ierrors, if_iqdrops); printf(" %qu packets output, %qu bytes, %qu errors, %qu unsupported\n", if_opackets, if_obytes, if_oerrors, if_noproto); if (if_ibytes && if_ipackets && (if_ibytes / if_ipackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf(" %qu input", if_ibytes / if_ipackets); pntd = 1; } else pntd = 0; if (if_obytes && if_opackets && (if_obytes / if_opackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf("%s%qu output", pntd ? ", " : " ", if_obytes / if_opackets); pntd = 1; } if (pntd) printf(" (average bytes/packet)\n"); switch(if_type) { /* * These appear to be the only interface types to increase collision * count in the OpenBSD 3.2 kernel. */ case IFT_ETHER: case IFT_SLIP: case IFT_PROPVIRTUAL: case IFT_IEEE80211: printf(" %qu collisions\n", if_collisions); break; default: break; } if(verbose) { if (flags) { printf(" Flags:\n "); bprintf(stdout, flags, ifnetflags); printf("\n"); } if (br) { if ((tmp = bridge_list(ifs, ifname, " ", tmp_str, sizeof(tmp_str), SHOW_STPSTATE))) { printf(" STP member state%s:\n", tmp > 1 ? "s" : ""); printf("%s", tmp_str); } bridge_addrs(ifs, ifname, " ", " "); } media_supported(ifs, ifname, " ", " "); } close(ifs); return(0); }
int show_int(int argc, char **argv) { struct ifaddrs *ifap, *ifa; struct if_nameindex *ifn_list, *ifnp; struct ifreq ifr, ifrdesc; struct if_data if_data; struct sockaddr_in *sin = NULL, *sinmask = NULL, *sindest; struct sockaddr_in6 *sin6 = NULL, *sin6mask = NULL, *sin6dest; struct timeval tv; short tmp; int ifs, br, flags, days, hours, mins, pntd; int ippntd = 0; int physrt, physttl; time_t c; char *type, *lladdr, *ifname = NULL; char tmp_str[512], tmp_str2[512], ifdescr[IFDESCRSIZE]; if (argc == 3) ifname = argv[2]; /* * Show all interfaces when no ifname specified. */ if (ifname == NULL) { if ((ifn_list = if_nameindex()) == NULL) { printf("%% show_int: if_nameindex failed\n"); return 0; } for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) { char *args[] = { NULL, NULL, ifnp->if_name }; show_int(3, args); } if_freenameindex(ifn_list); return(0); } else if (!is_valid_ifname(ifname)) { printf("%% interface %s not found\n", ifname); return(1); } if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("%% show_int: %s\n", strerror(errno)); return(1); } if (!(br = is_bridge(ifs, (char *)ifname))) br = 0; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); /* * Show up/down status and last change time */ flags = get_ifflags(ifname, ifs); ifr.ifr_data = (caddr_t)&if_data; if (ioctl(ifs, SIOCGIFDATA, (caddr_t)&ifr) < 0) { printf("%% show_int: SIOCGIFDATA: %s\n", strerror(errno)); close(ifs); return(1); } printf("%% %s", ifname); /* description */ memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, ifname, sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = (caddr_t)&ifdescr; if (ioctl(ifs, SIOCGIFDESCR, &ifrdesc) == 0 && strlen(ifrdesc.ifr_data)) printf(" (%s)", ifrdesc.ifr_data); putchar('\n'); printf(" %s is %s", br ? "Bridge" : "Interface", flags & IFF_UP ? "up" : "down"); if (if_data.ifi_lastchange.tv_sec) { gettimeofday(&tv, (struct timezone *)0); c = difftime(tv.tv_sec, if_data.ifi_lastchange.tv_sec); days = c / (24 * 60 * 60); c %= (24 * 60 * 60); hours = c / (60 * 60); c %= (60 * 60); mins = c / 60; c %= 60; printf(" (last change "); if (days) printf("%id ", days); printf("%02i:%02i:%02i)", hours, mins, (int)c); } printf(", protocol is %s", flags & IFF_RUNNING ? "up" : "down"); printf("\n"); type = iftype(if_data.ifi_type); printf(" Interface type %s", type); if (flags & IFF_BROADCAST) printf(" (Broadcast)"); else if (flags & IFF_POINTOPOINT) printf(" (PointToPoint)"); if ((lladdr = get_hwdaddr(ifname)) != NULL) printf(", hardware address %s", lladdr); printf("\n"); show_trunk(ifs, ifname); media_status(ifs, ifname, " Media type "); /* * Print interface IP address, and broadcast or * destination if available. But, don't print broadcast * if it is what we would expect given the ip and netmask! */ if (getifaddrs(&ifap) != 0) { printf("%% show_int: getifaddrs failed: %s\n", strerror(errno)); return(1); } /* * Cycle through getifaddrs for interfaces with our * desired name that sport AF_INET, print the IP and * related information. */ for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (strncmp(ifname, ifa->ifa_name, IFNAMSIZ)) continue; switch (ifa->ifa_addr->sa_family) { case AF_INET: sin = (struct sockaddr_in *)ifa->ifa_addr; sinmask = (struct sockaddr_in *)ifa->ifa_netmask; if (sin->sin_addr.s_addr == INADDR_ANY) continue; break; case AF_INET6: sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; sin6mask = (struct sockaddr_in6 *)ifa->ifa_netmask; if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) continue; in6_fillscopeid(sin6); break; default: continue; } if (!ippntd) printf(" Internet address"); printf("%s %s", ippntd ? "," : "", ifa->ifa_addr->sa_family == AF_INET ? netname4(sin->sin_addr.s_addr, sinmask) : netname6(sin6, sin6mask)); ippntd = 1; switch (ifa->ifa_addr->sa_family) { case AF_INET: if (flags & IFF_POINTOPOINT) { sindest = (struct sockaddr_in *) ifa->ifa_dstaddr; printf(" (Destination %s)", routename4(sindest->sin_addr.s_addr)); } else if (flags & IFF_BROADCAST) { sindest = (struct sockaddr_in *) ifa->ifa_broadaddr; /* * no reason to show the broadcast addr * if it is standard (this should always * be true unless someone has messed up their * network or they are playing around...) */ if (ntohl(sindest->sin_addr.s_addr) != in4_brdaddr(sin->sin_addr.s_addr, sinmask->sin_addr.s_addr) && ntohl(sindest->sin_addr.s_addr) != INADDR_ANY) printf(" (Broadcast %s)", inet_ntoa(sindest->sin_addr)); } break; case AF_INET6: if (flags & IFF_POINTOPOINT) { sin6dest = (struct sockaddr_in6 *) ifa->ifa_dstaddr; in6_fillscopeid(sin6dest); printf(" (Destination %s)", routename6(sin6dest)); } break; default: printf(" unknown"); break; } } if (ippntd) { printf("\n"); } freeifaddrs(ifap); if (!br) { if (phys_status(ifs, ifname, tmp_str, tmp_str2, sizeof(tmp_str), sizeof(tmp_str2)) > 0) { printf(" Tunnel source %s destination %s", tmp_str, tmp_str2); if (((physrt = get_physrtable(ifs, ifname)) != 0)) printf(" destination rdomain %i", physrt); if (((physttl = get_physttl(ifs, ifname)) != 0)) printf(" ttl %i", physttl); printf("\n"); } carp_state(ifs, ifname); printf(" "); show_vnet_parent(ifs, ifname); if (ioctl(ifs, SIOCGIFRDOMAIN, (caddr_t)&ifr) != -1) printf(" rdomain %d,", ifr.ifr_rdomainid); /* * Display MTU, line rate */ printf(" MTU %u bytes", if_data.ifi_mtu); if (ioctl(ifs, SIOCGIFHARDMTU, (caddr_t)&ifr) != -1) { if (ifr.ifr_hardmtu) printf(" (hardmtu %u)", ifr.ifr_hardmtu); } if (if_data.ifi_baudrate) printf(", Line Rate %qu %s", MBPS(if_data.ifi_baudrate) ? MBPS(if_data.ifi_baudrate) : if_data.ifi_baudrate / 1000, MBPS(if_data.ifi_baudrate) ? "Mbps" : "Kbps"); printf("\n"); } if (get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWID) != 0) { printf(" SSID %s", tmp_str); if(get_nwinfo(ifname, tmp_str, sizeof(tmp_str), NWKEY) != 0) printf(", key %s", tmp_str); if ((tmp = get_nwinfo(ifname, tmp_str, sizeof(tmp_str), POWERSAVE)) != 0) printf(", powersaving (%s ms)\n", tmp_str); printf("\n"); } /* * Display remaining info from if_data structure */ printf(" %qu packets input, %qu bytes, %qu errors, %qu drops\n", if_data.ifi_ipackets, if_data.ifi_ibytes, if_data.ifi_ierrors, if_data.ifi_iqdrops); printf(" %qu packets output, %qu bytes, %qu errors, %qu unsupported\n", if_data.ifi_opackets, if_data.ifi_obytes, if_data.ifi_oerrors, if_data.ifi_noproto); if (if_data.ifi_ibytes && if_data.ifi_ipackets && (if_data.ifi_ibytes / if_data.ifi_ipackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf(" %qu input", if_data.ifi_ibytes / if_data.ifi_ipackets); pntd = 1; } else pntd = 0; if (if_data.ifi_obytes && if_data.ifi_opackets && (if_data.ifi_obytes / if_data.ifi_opackets) >= ETHERMIN) { /* < ETHERMIN means byte counter probably rolled over */ printf("%s%qu output", pntd ? ", " : " ", if_data.ifi_obytes / if_data.ifi_opackets); pntd = 1; } if (pntd) printf(" (average bytes/packet)\n"); switch(if_data.ifi_type) { /* * These appear to be the only interface types to increase collision * count in the OpenBSD 3.2 kernel. */ case IFT_ETHER: case IFT_SLIP: case IFT_PROPVIRTUAL: case IFT_IEEE80211: printf(" %qu collisions\n", if_data.ifi_collisions); break; default: break; } if(verbose) { if (flags) { printf(" Flags:\n "); bprintf(stdout, flags, ifnetflags); printf("\n"); } printifhwfeatures(ifs, ifname); if (br) { if ((tmp = bridge_list(ifs, ifname, " ", tmp_str, sizeof(tmp_str), SHOW_STPSTATE))) { printf(" STP member state%s:\n", tmp > 1 ? "s" : ""); printf("%s", tmp_str); } bridge_addrs(ifs, ifname, " ", " "); } media_supported(ifs, ifname, " ", " "); } close(ifs); return(0); }
CubitStatus CAMergePartner::actuate_list(DLIList<RefEntity*> entity_list) { // given a list of ref entities (usually all entities of a given type), // actuate the camp's on those entities RefEntity *ref_ent, *keeper; DLIList<CubitAttrib*> ca_list; DLIList<TopologyBridge*> bridge_list(entity_list.size()); SDLCAMergePartnerList sorted_camp_list; int i; for(i = entity_list.size(); i > 0; i--) { ref_ent = entity_list.get_and_step(); ca_list.clean_out(); ref_ent->find_cubit_attrib_type(CA_MERGE_PARTNER, ca_list); assert(ca_list.size() < 2); // There should only be one // merge partner per entity if(ca_list.size() > 0) { CAMergePartner* attrib = dynamic_cast<CAMergePartner*>(ca_list.get()); sorted_camp_list.append( attrib ); TopologyEntity* te = dynamic_cast<TopologyEntity*>(ref_ent); TopologyBridge* bridge = te->bridge_manager()->topology_bridge(); bridge_list.append(bridge); } } sorted_camp_list.sort(); sorted_camp_list.reset(); if (DEBUG_FLAG(90)) { for (i = sorted_camp_list.size(); i > 0; i--) { CAMergePartner *camp_ptr = sorted_camp_list.get_and_step(); ref_ent = camp_ptr->attrib_owner(); PRINT_DEBUG_90("%s %d, unique id = %d\n", ref_ent->class_name(), ref_ent->id(), camp_ptr->merge_id()); } } // now go through all the camp's for the entity list; peel off // camp's with the same id, and merge the associated entities together while (sorted_camp_list.size() > 0) { DLIList<RefEntity*> refent_list; DLIList<CubitAttrib*> camp_list; keeper = NULL; // get the next list of entities with the same camp id sorted_camp_list.last(); CAMergePartner *camp_ptr = sorted_camp_list.remove(); sorted_camp_list.back(); camp_list.append(camp_ptr); int current_id = camp_ptr->merge_id(); while (sorted_camp_list.size() > 0 && sorted_camp_list.get()->merge_id() == current_id) { camp_list.append(sorted_camp_list.remove()); sorted_camp_list.back(); } if (camp_list.size() == 1) continue; CubitBoolean has_actuated = camp_list.get()->has_actuated(); // check the has actuated flag; if one is set, they all should be; // also, compile list of ref entities while we're at it for (current_id = camp_list.size(); current_id > 0; current_id--) { ref_ent = camp_list.get()->attrib_owner(); refent_list.append(ref_ent); if (!keeper || ref_ent->id() < keeper->id()) keeper = ref_ent; assert(camp_list.get()->has_actuated() == has_actuated); camp_list.step(); } // if they have already actuated, go on to next ones if (has_actuated == CUBIT_TRUE) continue; // otherwise merge if(refent_list.size() > 1) MergeTool::instance()->force_merge(refent_list); // remove the cubit attribute from the surviving parent keeper->remove_cubit_attrib(CA_MERGE_PARTNER); } // loop over existing camp's return CUBIT_SUCCESS; }