summaryrefslogtreecommitdiffstats
path: root/src/plugins/dpdk/thread.c
blob: 3a3fcc6cea6b7c097de151fca84e9345849026ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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 <rte_config.h>

#include <rte_common.h>
#include <rte_log.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_ring.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_version.h>

#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <dpdk/device/dpdk.h>
#include <dpdk/device/dpdk_priv.h>

static clib_error_t *
dpdk_launch_thread (void *fp, vlib_worker_thread_t * w, unsigned lcore_id)
{
  int r;
  r = rte_eal_remote_launch (fp, (void *) w, lcore_id);
  if (r)
    return clib_error_return (0, "Failed to launch thread %u", lcore_id);
  return 0;
}

static clib_error_t *
dpdk_thread_set_lcore (u32 thread, u16 lcore)
{
  return 0;
}

static vlib_thread_callbacks_t callbacks = {
  .vlib_launch_thread_cb = &dpdk_launch_thread,
  .vlib_thread_set_lcore_cb = &dpdk_thread_set_lcore,
};

static clib_error_t *
dpdk_thread_init (vlib_main_t * vm)
{
  vlib_thread_cb_register (vm, &callbacks);
  return 0;
}

VLIB_INIT_FUNCTION (dpdk_thread_init);

/** @endcond */
/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */

#ifndef __VOM_TYPES_H__
#define __VOM_TYPES_H__

#include <array>
#include <vector>

#include <boost/asio/ip/address.hpp>

#include "vom/enum_base.hpp"

/**
 * Convenince wrapper macro for error handling in VAPI sends
 */
#define VAPI_CALL(_stmt)                                                       \
  {                                                                            \
    vapi_error_e _rv;                                                          \
    do {                                                                       \
      _rv = (_stmt);                                                           \
    } while (VAPI_OK != _rv);                                                  \
  }

namespace VOM {
/**
 * There needs to be a strict order in which object types are read from VPP
 *  (at boot time) and replayed to VPP (if VPP restarts). That ordering is
 * defined in this enum types
 */
enum class dependency_t
{
  /**
   * Global Configuration has no dependency
   */
  GLOBAL = 0,

  /**
   * interfaces are the root of the dependency graph
   */
  INTERFACE,

  /**
   * bond group binding is after interfaces but before
   * anything else
   */
  BOND_BINDING,

  /**
   * Tunnel or virtual interfaces next
   */
  TUNNEL,

  /**
   * Tables in which entries are added, e.g bridge/route-domains
   */
  TABLE,

  /**
   * ACLs
   */
  ACL,

  /**
   * Then L2/objects that bind to interfaces, BD, ACLS, etc
   */
  BINDING,

  /**
   * Entries in Tables
   */
  ENTRY,
};

/**
 * Error codes that VPP will return during a HW write
 */
struct rc_t : public enum_base<rc_t>
{
  rc_t(const rc_t& rc) = default;

  /**
   * Destructor
   */
  ~rc_t();

  /**
   * The value un-set
   */
  const static rc_t UNSET;

  /**
   * The HW write/update action was/has not been attempted
   */
  const static rc_t NOOP;

  /**
   * The HW write was successfull
   */
  const static rc_t OK;

  /**
   * HW write reported invalid input
   */
  const static rc_t INVALID;

  /**
   * HW write timedout - VPP did not respond within a timely manner
   */
  const static rc_t TIMEOUT;

  /**
   * Get the rc_t from the VPP API value
   */
  static const rc_t& from_vpp_retval(int32_t rv);

private:
  /**
   * Constructor
   */
  rc_t(int v, const std::string s);
};

/**
 * Feature Directions
 */
struct direction_t : public enum_base<direction_t>
{
  /**
   * Constructor
   */
  direction_t(int v, const std::string s);

  /**
   * Destructor
   */
  ~direction_t() = default;

  /**
   * Permit Direction
   */
  const static direction_t INPUT;

  /**
   * Deny Direction
   */
  const static direction_t OUTPUT;
};

/**
 * Output ostream for direction_t
 */
std::ostream& operator<<(std::ostream& os, const direction_t& dir);

/**
 * Feature Ethertype
 */
struct ethertype_t : public enum_base<ethertype_t>
{
  /**
   * Constructor
   */
  ethertype_t(int v, const std::string s);

  /**
   * Destructor
   */
  ~ethertype_t() = default;

  /**
   * Ethertype Arp
   */
  const static ethertype_t ARP;

  /**
   * Ethertype FCoE
   */
  const static ethertype_t FCOE;

  /**
   * Ethertype IPv4
   */
  const static ethertype_t IPV4;

  /**
   * Ethertype Ipv6
   */
  const static ethertype_t IPV6;

  /**
   * Ethertype MAC Security
   */
  const static ethertype_t MAC_SECURITY;

  /**
   * Ethertype MPLS unicast
   */
  const static ethertype_t MPLS_UNICAST;

  /**
   * Ethertype TRILL
   */
  const static ethertype_t TRILL;

  /**
   * Ethertype Unspecified
   */
  const static ethertype_t UNSPECIFIED;

  /**
   * Get the ethertype from the numeric value
   */
  static const ethertype_t& from_numeric_val(uint16_t numeric);
};

/**
 * Output ostream for ethertype_t
 */
std::ostream& operator<<(std::ostream& os, const ethertype_t& eth);

/**
 * A type declaration of an interface handle in VPP
 */
struct handle_t
{
  /**
   * Constructor
   */
  handle_t(int value);

  /**
   * Constructor
   */
  handle_t();

  /**
   * convert to string format for debug purposes
   */
  std::string to_string() const;

  /**
   * Comparison operator
   */
  bool operator==(const handle_t& other) const;

  /**
   * Comparison operator
   */
  bool operator!=(const handle_t& other) const;

  /**
   * less than operator
   */
  bool operator<(const handle_t& other) const;

  /**
   * A value of an interface handle_t that means the itf does not exist
   */
  const static handle_t INVALID;

  /**
   * get the value of the handle
   */
  uint32_t value() const;

  /**
   * reset the value of the handle to ~0
   */
  void reset();

private:
  /**
   * VPP's handle value
   */
  uint32_t m_value;
};

/**
 * ostream print of a handle_t
 */
std::ostream& operator<<(std::ostream& os, const handle_t& h);

/**
 * Type def of a Ethernet address
 */
struct mac_address_t
{
  mac_address_t(uint8_t bytes[6]);
  mac_address_t(const std::string& str);
  mac_address_t(std::initializer_list<uint8_t> bytes);
  /**
   * Convert to byte array
   */
  void to_bytes(uint8_t* array, uint8_t len) const;

  /**
   * An all 1's MAC address
   */
  const static mac_address_t ONE;

  /**
   * An all 0's MAC address
   */
  const static mac_address_t ZERO;

  /**
   * Comparison operator
   */
  bool operator==(const mac_address_t& m) const;

  /**
   * less than operator
   */
  bool operator<(const mac_address_t& m) const;

  /**
   * String conversion
   */
  std::string to_string() const;

  /**
   * Underlying bytes array
   */
  std::array<uint8_t, 6> bytes;
};

/**
 * Type def of a L2 address as read from VPP
 */
struct l2_address_t
{
  l2_address_t(const uint8_t bytes[8], uint8_t n_bytes);
  l2_address_t(std::initializer_list<uint8_t> bytes);
  l2_address_t(const mac_address_t& mac);

  /**
   * Convert to byte array
   */
  void to_bytes(uint8_t* array, uint8_t len) const;

  /**
   * An all 1's L2 address
   */
  const static l2_address_t ONE;

  /**
   * An all 0's L2 address
   */
  const static l2_address_t ZERO;

  /**
   * Comparison operator
   */
  bool operator==(const l2_address_t& m) const;

  /**
   * Comparison operator
   */
  bool operator!=(const l2_address_t& m) const;

  /**
   * String conversion
   */
  std::string to_string() const;

  /**
   * MAC address conversion
   */
  mac_address_t to_mac() const;

  /**
   * Underlying bytes array - filled from least to most significant
   */
  std::vector<uint8_t> bytes;
};

/**
 * Ostream operator for a MAC address
 */
std::ostream& operator<<(std::ostream& os, const mac_address_t& mac);

/**
 * Ostream operator for a MAC address
 */
std::ostream& operator<<(std::ostream& os, const l2_address_t& l2);
};

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "mozilla")
 * End:
 */

#endif