<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <cassert>
#include <cstring>
#include <map>
#include <utility>
#include <linux/if_packet.h>
#include <linux/if_bridge.h>

#include <glog/logging.h>
#include <netlink/route/link.h>
#include <netlink/route/bridge_vlan.h>
#ifdef HAVE_NETLINK_ROUTE_MDB_H
#include <netlink/route/mdb.h>
#endif
#include <netlink/route/link/vlan.h>
#include <netlink/route/link/vxlan.h>
#include <netlink/route/neighbour.h>
#include <rofl/common/openflow/cofport.h>

#include "cnetlink.h"
#include "netlink-utils.h"
#include "nl_bridge.h"
#include "nl_output.h"
#include "nl_vlan.h"
#include "nl_vxlan.h"
#include "sai.h"
#include "tap_manager.h"

namespace basebox {

nl_bridge::nl_bridge(switch_interface *sw, std::shared_ptr<tap_manager> tap_man,
                     cnetlink *nl, std::shared_ptr<nl_vlan> vlan,
                     std::shared_ptr<nl_vxlan> vxlan)
    : bridge(nullptr), sw(sw), tap_man(std::move(tap_man)), nl(nl),
      vlan(std::move(vlan)), vxlan(std::move(vxlan)),
      l2_cache(nl_cache_alloc(nl_cache_ops_lookup("route/neigh")),
               nl_cache_free) {
  memset(&empty_br_vlan, 0, sizeof(rtnl_link_bridge_vlan));
  memset(&vxlan_dom_bitmap, 0, sizeof(vxlan_dom_bitmap));
}

nl_bridge::~nl_bridge() { rtnl_link_put(bridge); }

static rofl::caddress_in4 libnl_in4addr_2_rofl(struct nl_addr *addr, int *rv) {
  struct sockaddr_in sin;
  socklen_t salen = sizeof(sin);

  assert(rv);
  *rv = nl_addr_fill_sockaddr(addr, (struct sockaddr *)&sin, &salen);
  return rofl::caddress_in4(&sin, salen);
}

void nl_bridge::set_bridge_interface(rtnl_link *bridge) {
  assert(bridge);
  assert((rtnl_link_get_type(bridge) != nullptr &&
          std::string("bridge").compare(rtnl_link_get_type(bridge)) == 0) ||
         (rtnl_link_get_family(bridge) == AF_BRIDGE &&
          rtnl_link_get_ifindex(bridge) == rtnl_link_get_master(bridge)));

  this->bridge = bridge;
  nl_object_get(OBJ_CAST(bridge));

  if (!get_vlan_filtering())
    LOG(FATAL) << __FUNCTION__
               << " unsupported: bridge configured with vlan_filtering 0";
}

bool nl_bridge::is_bridge_interface(rtnl_link *link) {
  assert(link);

  if (rtnl_link_get_ifindex(link) != rtnl_link_get_ifindex(bridge))
    return false;

  // TODO compare more?

  return true;
// Read sysfs to obtain the value for STP state on a bridge
uint32_t nl_bridge::get_stp_state() {<commit_msg>nl_bridge: add function to simplify checking is_bridge_interface<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <cassert>
#include <cstring>
#include <map>
#include <utility>
#include <linux/if_packet.h>
#include <linux/if_bridge.h>

#include <glog/logging.h>
#include <netlink/route/link.h>
#include <netlink/route/bridge_vlan.h>
#ifdef HAVE_NETLINK_ROUTE_MDB_H
#include <netlink/route/mdb.h>
#endif
#include <netlink/route/link/vlan.h>
#include <netlink/route/link/vxlan.h>
#include <netlink/route/neighbour.h>
#include <rofl/common/openflow/cofport.h>

#include "cnetlink.h"
#include "netlink-utils.h"
#include "nl_bridge.h"
#include "nl_output.h"
#include "nl_vlan.h"
#include "nl_vxlan.h"
#include "sai.h"
#include "tap_manager.h"

namespace basebox {

nl_bridge::nl_bridge(switch_interface *sw, std::shared_ptr<tap_manager> tap_man,
                     cnetlink *nl, std::shared_ptr<nl_vlan> vlan,
                     std::shared_ptr<nl_vxlan> vxlan)
    : bridge(nullptr), sw(sw), tap_man(std::move(tap_man)), nl(nl),
      vlan(std::move(vlan)), vxlan(std::move(vxlan)),
      l2_cache(nl_cache_alloc(nl_cache_ops_lookup("route/neigh")),
               nl_cache_free) {
  memset(&empty_br_vlan, 0, sizeof(rtnl_link_bridge_vlan));
  memset(&vxlan_dom_bitmap, 0, sizeof(vxlan_dom_bitmap));
}

nl_bridge::~nl_bridge() { rtnl_link_put(bridge); }

static rofl::caddress_in4 libnl_in4addr_2_rofl(struct nl_addr *addr, int *rv) {
  struct sockaddr_in sin;
  socklen_t salen = sizeof(sin);

  assert(rv);
  *rv = nl_addr_fill_sockaddr(addr, (struct sockaddr *)&sin, &salen);
  return rofl::caddress_in4(&sin, salen);
}

void nl_bridge::set_bridge_interface(rtnl_link *bridge) {
  assert(bridge);
  assert((rtnl_link_get_type(bridge) != nullptr &&
          std::string("bridge").compare(rtnl_link_get_type(bridge)) == 0) ||
         (rtnl_link_get_family(bridge) == AF_BRIDGE &&
          rtnl_link_get_ifindex(bridge) == rtnl_link_get_master(bridge)));

  this->bridge = bridge;
  nl_object_get(OBJ_CAST(bridge));

  if (!get_vlan_filtering())
    LOG(FATAL) << __FUNCTION__
               << " unsupported: bridge configured with vlan_filtering 0";
}

bool nl_bridge::is_bridge_interface(int ifindex) {
  assert(bridge);

  return (ifindex == rtnl_link_get_ifindex(bridge)) ? true : false;
}

bool nl_bridge::is_bridge_interface(rtnl_link *link) {
  assert(bridge);
  assert(link);

  return is_bridge_interface(rtnl_link_get_ifindex(link));
}

// Read sysfs to obtain the value for STP state on a bridge
uint32_t nl_bridge::get_stp_state() {
{'fraction_non_alphanumeric': 0.13882087022038048, 'fraction_numerical': 0.00565078169146732, 'mean_word_length': 4.848017621145375, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '780262', 'n_tokens_mistral': 2048, 'n_tokens_neox': 2008, 'n_words': 380}