<commit_before>/*
 * Copyright (C) 2010-2016 Red Hat, Inc.
 * Copyright (C) 2010-2012 IBM Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *     <NAME> <<EMAIL>>
 *
 * Notes:
 * netlink: http://lovezutto.googlepages.com/netlink.pdf
 *          iproute2 package
 *
 */

#include <config.h>

#include "virnetdevmacvlan.h"
#include "virmacaddr.h"
#include "virerror.h"
#include "virthread.h"
#include "virstring.h"

#define VIR_FROM_THIS VIR_FROM_NET

VIR_ENUM_IMPL(virNetDevMacVLanMode, VIR_NETDEV_MACVLAN_MODE_LAST,
              "vepa",
              "private",
              "bridge",
              "passthrough")

#if WITH_MACVTAP
# include <stdint.h>
# include <stdio.h>
# include <errno.h>
# include <fcntl.h>
# include <sys/socket.h>
# include <sys/ioctl.h>

# include <net/if.h>
# include <linux/if_tun.h>

/* Older kernels lacked this enum value.  */
# if !HAVE_DECL_MACVLAN_MODE_PASSTHRU
#  define MACVLAN_MODE_PASSTHRU 8
# endif

# include "viralloc.h"
# include "virlog.h"
# include "viruuid.h"
# include "virfile.h"
# include "virnetlink.h"
# include "virnetdev.h"
# include "virpidfile.h"
# include "virbitmap.h"

VIR_LOG_INIT("util.netdevmacvlan");

# define MACVTAP_NAME_PREFIX	"macvtap"
# define MACVTAP_NAME_PATTERN	"macvtap%d"

# define MACVLAN_NAME_PREFIX	"macvlan"
# define MACVLAN_NAME_PATTERN	"macvlan%d"

# define MACVLAN_MAX_ID 8191

virMutex virNetDevMacVLanCreateMutex = VIR_MUTEX_INITIALIZER;
virBitmapPtr macvtapIDs = NULL;
virBitmapPtr macvlanIDs = NULL;

static int
virNetDevMacVLanOnceInit(void)
{

    if (!macvtapIDs &&
        !(macvtapIDs = virBitmapNew(MACVLAN_MAX_ID + 1)))
        return -1;
    if (!macvlanIDs &&
        !(macvlanIDs = virBitmapNew(MACVLAN_MAX_ID + 1)))
        return -1;
    return 0;
}

VIR_ONCE_GLOBAL_INIT(virNetDevMacVLan);


/**
 * virNetDevMacVLanReserveID:
 *
 *  @id: id 0 - MACVLAN_MAX_ID+1 to reserve (or -1 for "first free")
 *  @flags: set VIR_NETDEV_MACVLAN_CREATE_WITH_TAP for macvtapN else macvlanN
 *  @quietFail: don't log an error if this name is already in-use
 *  @nextFree: reserve the next free ID *after* @id rather than @id itself
 *
 *  Reserve the indicated ID in the appropriate bitmap, or find the
 *  first free ID if @id is -1.
 *
 *  Returns newly reserved ID# on success, or -1 to indicate failure.
 */
static int
virNetDevMacVLanReserveID(int id, unsigned int flags,
                          bool quietFail, bool nextFree)
{
    virBitmapPtr bitmap;

    if (virNetDevMacVLanInitialize() < 0)
       return -1;

    bitmap = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
        macvtapIDs :  macvlanIDs;

    if (id > MACVLAN_MAX_ID) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("can't use name %s%d - out of range 0-%d"),
                       (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
                       MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX,
                       id, MACVLAN_MAX_ID);
        return -1;
    }

    if ((id < 0 || nextFree) &&
        (id = virBitmapNextClearBit(bitmap, 0)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("no unused %s names available"),
                       (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
                       MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX);
        return -1;
    }

    if (virBitmapIsBitSet(bitmap, id)) {
        if (quietFail) {
            VIR_INFO("couldn't reserve name %s%d - already in use",
                     (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
                     MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id);
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("couldn't reserve name %s%d - already in use"),
                           (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
                           MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id);
        }
        return -1;
    }

    if (virBitmapSetBit(bitmap, id) < 0) {<commit_msg>util: avoid getting stuck on macvtapN name created outside libvirt<commit_after>/*
 * Copyright (C) 2010-2016 Red Hat, Inc.
 * Copyright (C) 2010-2012 IBM Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *     <NAME> <<EMAIL>>
 *
 * Notes:
 * netlink: http://lovezutto.googlepages.com/netlink.pdf
 *          iproute2 package
 *
 */

#include <config.h>

#include "virnetdevmacvlan.h"
#include "virmacaddr.h"
#include "virerror.h"
#include "virthread.h"
#include "virstring.h"

#define VIR_FROM_THIS VIR_FROM_NET

VIR_ENUM_IMPL(virNetDevMacVLanMode, VIR_NETDEV_MACVLAN_MODE_LAST,
              "vepa",
              "private",
              "bridge",
              "passthrough")

#if WITH_MACVTAP
# include <stdint.h>
# include <stdio.h>
# include <errno.h>
# include <fcntl.h>
# include <sys/socket.h>
# include <sys/ioctl.h>

# include <net/if.h>
# include <linux/if_tun.h>

/* Older kernels lacked this enum value.  */
# if !HAVE_DECL_MACVLAN_MODE_PASSTHRU
#  define MACVLAN_MODE_PASSTHRU 8
# endif

# include "viralloc.h"
# include "virlog.h"
# include "viruuid.h"
# include "virfile.h"
# include "virnetlink.h"
# include "virnetdev.h"
# include "virpidfile.h"
# include "virbitmap.h"

VIR_LOG_INIT("util.netdevmacvlan");

# define MACVTAP_NAME_PREFIX	"macvtap"
# define MACVTAP_NAME_PATTERN	"macvtap%d"

# define MACVLAN_NAME_PREFIX	"macvlan"
# define MACVLAN_NAME_PATTERN	"macvlan%d"

# define MACVLAN_MAX_ID 8191

virMutex virNetDevMacVLanCreateMutex = VIR_MUTEX_INITIALIZER;
virBitmapPtr macvtapIDs = NULL;
virBitmapPtr macvlanIDs = NULL;

static int
virNetDevMacVLanOnceInit(void)
{

    if (!macvtapIDs &&
        !(macvtapIDs = virBitmapNew(MACVLAN_MAX_ID + 1)))
        return -1;
    if (!macvlanIDs &&
        !(macvlanIDs = virBitmapNew(MACVLAN_MAX_ID + 1)))
        return -1;
    return 0;
}

VIR_ONCE_GLOBAL_INIT(virNetDevMacVLan);


/**
 * virNetDevMacVLanReserveID:
 *
 *  @id: id 0 - MACVLAN_MAX_ID+1 to reserve (or -1 for "first free")
 *  @flags: set VIR_NETDEV_MACVLAN_CREATE_WITH_TAP for macvtapN else macvlanN
 *  @quietFail: don't log an error if this name is already in-use
 *  @nextFree: reserve the next free ID *after* @id rather than @id itself
 *
 *  Reserve the indicated ID in the appropriate bitmap, or find the
 *  first free ID if @id is -1.
 *
 *  Returns newly reserved ID# on success, or -1 to indicate failure.
 */
static int
virNetDevMacVLanReserveID(int id, unsigned int flags,
                          bool quietFail, bool nextFree)
{
    virBitmapPtr bitmap;

    if (virNetDevMacVLanInitialize() < 0)
       return -1;

    bitmap = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
        macvtapIDs :  macvlanIDs;

    if (id > MACVLAN_MAX_ID) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("can't use name %s%d - out of range 0-%d"),
                       (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
                       MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX,
                       id, MACVLAN_MAX_ID);
        return -1;
    }

    if ((id < 0 || nextFree) &&
        (id = virBitmapNextClearBit(bitmap, id)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("no unused %s names available"),
                       (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
                       MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX);
        return -1;
    }

    if (virBitmapIsBitSet(bitmap, id)) {
        if (quietFail) {
            VIR_INFO("couldn't reserve name %s%d - already in use",
                     (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
                     MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id);
        } else {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("couldn't reserve name %s%d - already in use"),
                           (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
                           MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id);
        }
        return -1;
    }

    if (virBitmapSetBit(bitmap, id) < 0) {
{'fraction_non_alphanumeric': 0.0965970277837605, 'fraction_numerical': 0.009368942494077106, 'mean_word_length': 2.732717041800643, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7458425', 'n_tokens_mistral': 3248, 'n_tokens_neox': 3156, 'n_words': 819}