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;
}
Example #3
0
/*
 * 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;
        }
    }