int of_list_bsn_interface_first(of_list_bsn_interface_t *list, of_object_t *obj) { int rv; of_bsn_interface_init(obj, list->version, -1, 1); if ((rv = of_list_first(list, obj)) < 0) { return rv; } return rv; }
int of_list_bsn_interface_first(of_list_bsn_interface_t *list, of_bsn_interface_t *obj) { int rv; of_bsn_interface_init(obj, list->version, 0, 1); if ((rv = of_list_first((of_object_t *)list, (of_object_t *)obj)) < 0) { return rv; } of_object_wire_init((of_object_t *) obj, OF_BSN_INTERFACE, list->length); if (obj->length == 0) { return OF_ERROR_PARSE; } return rv; }
/* * This code uses getifaddrs to get both the IPv4 (AF_INET family) and MAC * (AF_PACKET family) addresses for each interface. Since getifaddrs returns * these separately, we first add list entries for each AF_INET address and * then for each entry find the AF_PACKET address with the same name. */ static indigo_error_t ind_ovs_handle_bsn_get_interfaces_request( of_bsn_get_interfaces_request_t *request, indigo_cxn_id_t cxn_id) { of_bsn_get_interfaces_reply_t *reply; uint32_t xid; struct ifaddrs *ifaddr, *ifa; of_list_bsn_interface_t list[1]; of_bsn_interface_t entry[1]; int rv; reply = of_bsn_get_interfaces_reply_new(request->version); if (reply == NULL) { return INDIGO_ERROR_RESOURCE; } of_bsn_get_interfaces_request_xid_get(request, &xid); of_bsn_get_interfaces_reply_xid_set(reply, xid); of_bsn_get_interfaces_reply_interfaces_bind(reply, list); if (getifaddrs(&ifaddr) == -1) { abort(); } /* Add each interface with an IP */ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { struct sockaddr_in *sa, *sa_mask; if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET) { continue; } if (strncmp(tunnel_ifname, ifa->ifa_name, sizeof(of_port_name_t))) { continue; } sa = (struct sockaddr_in *)ifa->ifa_addr; sa_mask = (struct sockaddr_in *)ifa->ifa_netmask; of_bsn_interface_init(entry, request->version, -1, 1); if (of_list_bsn_interface_append_bind(list, entry) < 0) { LOG_WARN("unable to reply with all interfaces"); break; } of_bsn_interface_name_set(entry, ifa->ifa_name); of_bsn_interface_ipv4_addr_set(entry, ntohl(sa->sin_addr.s_addr)); of_bsn_interface_ipv4_netmask_set(entry, ntohl(sa_mask->sin_addr.s_addr)); } /* Fill in MAC addrs from AF_PACKET addresses */ OF_LIST_BSN_INTERFACE_ITER(list, entry, rv) { of_port_name_t entry_name; of_bsn_interface_name_get(entry, &entry_name); for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { struct sockaddr_ll *sa; of_mac_addr_t hw_addr; if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_PACKET || strncmp(ifa->ifa_name, entry_name, sizeof(of_port_name_t))) { continue; } sa = (struct sockaddr_ll *)ifa->ifa_addr; memcpy(hw_addr.addr, sa->sll_addr, OF_MAC_ADDR_BYTES); of_bsn_interface_hw_addr_set(entry, hw_addr); break; } }