<commit_before>/****************************************************************
 *
 *        Copyright 2013, Big Switch Networks, Inc.
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *        http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific
 * language governing permissions and limitations under the
 * License.
 *
 ****************************************************************/

#include "ovs_driver_int.h"
#include "OVSDriver/ovsdriver_config.h"
#include <stdlib.h>
#include <assert.h>
#include <net/if.h>
#include <string.h>
#include <errno.h>
#include <ifaddrs.h>
#include <linux/if_packet.h>
#include "indigo/types.h"
#include "murmur/murmur.h"
#include "SocketManager/socketmanager.h"
#include "indigo/of_state_manager.h"

static int ind_ovs_create_datapath(const char *name);
static int ind_ovs_destroy_datapath(void);
static void setup_inband(void);

/* Log module "ovsdriver" */
AIM_LOG_STRUCT_DEFINE(
    OVSDRIVER_CONFIG_LOG_OPTIONS_DEFAULT,
    OVSDRIVER_CONFIG_LOG_BITS_DEFAULT,
    NULL, /* Custom log map */
    OVSDRIVER_CONFIG_LOG_CUSTOM_BITS_DEFAULT);

int ind_ovs_dp_ifindex = 0;
struct nl_sock *ind_ovs_socket;
int ovs_datapath_family, ovs_packet_family, ovs_vport_family, ovs_flow_family;
bool ind_ovs_benchmark_mode = false;
bool ind_ovs_disable_kflows = false;
bool ind_ovs_disable_megaflows = false;
uint32_t ind_ovs_salt;
uint16_t ind_ovs_inband_vlan = VLAN_INVALID;

struct ind_ovs_pktin_socket ind_ovs_pktout_soc;

static int
ind_ovs_create_datapath(const char *name)
{
    int ret;

    assert(ind_ovs_dp_ifindex == 0);
    assert(strlen(name) < 256);

    if ((ind_ovs_dp_ifindex = if_nametoindex(name)) != 0) {
        /* Destroy existing datapath. */
        (void) ind_ovs_destroy_datapath();
    }

    LOG_INFO("Creating kernel datapath %s", name);
    struct nl_msg *msg = ind_ovs_create_nlmsg(ovs_datapath_family, OVS_DP_CMD_NEW);
    nla_put_string(msg, OVS_DP_ATTR_NAME, name);
    nla_put_u32(msg, OVS_DP_ATTR_UPCALL_PID, 0);
    ret = ind_ovs_transact(msg);
    if (ret != 0) {
        return ret;
    }

    ind_ovs_dp_ifindex = if_nametoindex(name);
    assert(ind_ovs_dp_ifindex > 0);

    if (ind_ovs_inband_vlan != VLAN_INVALID) {
        setup_inband();
    }

    return ret;
}

static int
ind_ovs_destroy_datapath(void)
{
    assert(ind_ovs_dp_ifindex != 0);
    struct nl_msg *msg = ind_ovs_create_nlmsg(ovs_datapath_family, OVS_DP_CMD_DEL);
    ind_ovs_dp_ifindex = 0;
    return ind_ovs_transact(msg);
}

/*
 * Generate a DPID.
 *
 * The upper 48 bits are the MAC address of the first NIC.
 * The lower 16 bits are the hash of the datapath name.
 */
static void
ind_ovs_dpid_set(const char *datapath_name)
{
    bool found = false;
    uint8_t mac[6];
    uint64_t dpid;
    struct ifaddrs *ifaddr, *ifa;

    if (getifaddrs(&ifaddr) == -1) {
        abort();
    }

    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        struct sockaddr_ll *sa = (struct sockaddr_ll *)ifa->ifa_addr;
        if (sa != NULL && sa->sll_family == AF_PACKET
            && !(ifa->ifa_flags & IFF_LOOPBACK)) {
            memcpy(mac, &sa->sll_addr, sizeof(mac));
            found = true;
            LOG_VERBOSE("using MAC from interface %s", ifa->ifa_name);
            break;
        }
    }

    if (!found) {
        uint32_t x = get_entropy();
        LOG_WARN("no NICs found, generating a random MAC address");
        mac[0] = 0x02; /* locally administered address */
        mac[1] = 0;
        mac[2] = x;
        mac[3] = x >> 8;
        mac[4] = x >> 16;
        mac[5] = x >> 24;
    }

    dpid = ((uint64_t)mac[0] << 40) | ((uint64_t)mac[1] << 32) | (mac[2] << 24) |
        (mac[3] << 16) | (mac[4] << 8) | mac[5];
    dpid |= (uint64_t)murmur_hash(datapath_name, strlen(datapath_name), 0x17ccd) << 48;
    indigo_core_dpid_set(dpid);

    freeifaddrs(ifaddr);<commit_msg>OVSDriver: fix shifting when constructing DPID from MAC<commit_after>/****************************************************************
 *
 *        Copyright 2013, Big Switch Networks, Inc.
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *        http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific
 * language governing permissions and limitations under the
 * License.
 *
 ****************************************************************/

#include "ovs_driver_int.h"
#include "OVSDriver/ovsdriver_config.h"
#include <stdlib.h>
#include <assert.h>
#include <net/if.h>
#include <string.h>
#include <errno.h>
#include <ifaddrs.h>
#include <linux/if_packet.h>
#include "indigo/types.h"
#include "murmur/murmur.h"
#include "SocketManager/socketmanager.h"
#include "indigo/of_state_manager.h"

static int ind_ovs_create_datapath(const char *name);
static int ind_ovs_destroy_datapath(void);
static void setup_inband(void);

/* Log module "ovsdriver" */
AIM_LOG_STRUCT_DEFINE(
    OVSDRIVER_CONFIG_LOG_OPTIONS_DEFAULT,
    OVSDRIVER_CONFIG_LOG_BITS_DEFAULT,
    NULL, /* Custom log map */
    OVSDRIVER_CONFIG_LOG_CUSTOM_BITS_DEFAULT);

int ind_ovs_dp_ifindex = 0;
struct nl_sock *ind_ovs_socket;
int ovs_datapath_family, ovs_packet_family, ovs_vport_family, ovs_flow_family;
bool ind_ovs_benchmark_mode = false;
bool ind_ovs_disable_kflows = false;
bool ind_ovs_disable_megaflows = false;
uint32_t ind_ovs_salt;
uint16_t ind_ovs_inband_vlan = VLAN_INVALID;

struct ind_ovs_pktin_socket ind_ovs_pktout_soc;

static int
ind_ovs_create_datapath(const char *name)
{
    int ret;

    assert(ind_ovs_dp_ifindex == 0);
    assert(strlen(name) < 256);

    if ((ind_ovs_dp_ifindex = if_nametoindex(name)) != 0) {
        /* Destroy existing datapath. */
        (void) ind_ovs_destroy_datapath();
    }

    LOG_INFO("Creating kernel datapath %s", name);
    struct nl_msg *msg = ind_ovs_create_nlmsg(ovs_datapath_family, OVS_DP_CMD_NEW);
    nla_put_string(msg, OVS_DP_ATTR_NAME, name);
    nla_put_u32(msg, OVS_DP_ATTR_UPCALL_PID, 0);
    ret = ind_ovs_transact(msg);
    if (ret != 0) {
        return ret;
    }

    ind_ovs_dp_ifindex = if_nametoindex(name);
    assert(ind_ovs_dp_ifindex > 0);

    if (ind_ovs_inband_vlan != VLAN_INVALID) {
        setup_inband();
    }

    return ret;
}

static int
ind_ovs_destroy_datapath(void)
{
    assert(ind_ovs_dp_ifindex != 0);
    struct nl_msg *msg = ind_ovs_create_nlmsg(ovs_datapath_family, OVS_DP_CMD_DEL);
    ind_ovs_dp_ifindex = 0;
    return ind_ovs_transact(msg);
}

/*
 * Generate a DPID.
 *
 * The upper 48 bits are the MAC address of the first NIC.
 * The lower 16 bits are the hash of the datapath name.
 */
static void
ind_ovs_dpid_set(const char *datapath_name)
{
    bool found = false;
    uint8_t mac[6];
    uint64_t dpid = 0;
    struct ifaddrs *ifaddr, *ifa;

    if (getifaddrs(&ifaddr) == -1) {
        abort();
    }

    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        struct sockaddr_ll *sa = (struct sockaddr_ll *)ifa->ifa_addr;
        if (sa != NULL && sa->sll_family == AF_PACKET
            && !(ifa->ifa_flags & IFF_LOOPBACK)) {
            memcpy(mac, &sa->sll_addr, sizeof(mac));
            found = true;
            LOG_VERBOSE("using MAC from interface %s", ifa->ifa_name);
            break;
        }
    }

    if (!found) {
        uint32_t x = get_entropy();
        LOG_WARN("no NICs found, generating a random MAC address");
        mac[0] = 0x02; /* locally administered address */
        mac[1] = 0;
        mac[2] = x;
        mac[3] = x >> 8;
        mac[4] = x >> 16;
        mac[5] = x >> 24;
    }

    int i;
    for (i = 0; i < sizeof(mac); i++) {
        dpid <<= 8;
        dpid |= mac[i];
    }

    dpid |= (uint64_t)murmur_hash(datapath_name, strlen(datapath_name), 0x17ccd) << 48;

    indigo_core_dpid_set(dpid);

    freeifaddrs(ifaddr);
{'fraction_non_alphanumeric': 0.1393674769884352, 'fraction_numerical': 0.016285107387302336, 'mean_word_length': 3.539367970005356, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 43, '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': '964414', 'n_tokens_mistral': 3205, 'n_tokens_neox': 3063, 'n_words': 721}