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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
|
/*
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* 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 NETDEV_H
#define NETDEV_H 1
#include "openvswitch/netdev.h"
#include "openvswitch/types.h"
#include "packets.h"
#include "flow.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Generic interface to network devices ("netdev"s).
*
* Every port on a switch must have a corresponding netdev that must minimally
* support a few operations, such as the ability to read the netdev's MTU.
* The Porting section of the documentation has more information in the
* "Writing a netdev Provider" section.
*
* Thread-safety
* =============
*
* Most of the netdev functions are fully thread-safe: they may be called from
* any number of threads on the same or different netdev objects. The
* exceptions are:
*
* netdev_rxq_recv()
* netdev_rxq_wait()
* netdev_rxq_drain()
*
* These functions are conditionally thread-safe: they may be called from
* different threads only on different netdev_rxq objects. (The client may
* create multiple netdev_rxq objects for a single netdev and access each
* of those from a different thread.)
*
* NETDEV_QUEUE_FOR_EACH
* netdev_queue_dump_next()
* netdev_queue_dump_done()
*
* These functions are conditionally thread-safe: they may be called from
* different threads only on different netdev_queue_dump objects. (The
* client may create multiple netdev_queue_dump objects for a single
* netdev and access each of those from a different thread.)
*/
struct dp_packet_batch;
struct dp_packet;
struct netdev_class;
struct netdev_rxq;
struct netdev_saved_flags;
struct ofpbuf;
struct in_addr;
struct in6_addr;
struct smap;
struct sset;
struct ovs_action_push_tnl;
enum netdev_pt_mode {
/* Unknown mode. The netdev is not configured yet. */
NETDEV_PT_UNKNOWN = 0,
/* The netdev is packet type aware. It can potentially carry any kind of
* packet. This "modern" mode is appropriate for both netdevs that handle
* only a single kind of packet (such as a virtual or physical Ethernet
* interface) and for those that can handle multiple (such as VXLAN-GPE or
* Geneve). */
NETDEV_PT_AWARE,
/* The netdev sends and receives only Ethernet frames. The netdev cannot
* carry packets other than Ethernet frames. This is a legacy mode for
* backward compability with controllers that are not prepared to handle
* OpenFlow 1.5+ "packet_type". */
NETDEV_PT_LEGACY_L2,
/* The netdev sends and receives only IPv4 and IPv6 packets. The netdev
* cannot carry Ethernet frames or other kinds of packets.
*
* IPv4 and IPv6 packets carried over the netdev are treated as Ethernet:
* when they are received, they are converted to Ethernet by adding a dummy
* header with the proper Ethertype; on tranmission, the Ethernet header is
* stripped. This is a legacy mode for backward compability with
* controllers that are not prepared to handle OpenFlow 1.5+
* "packet_type". */
NETDEV_PT_LEGACY_L3,
};
enum netdev_srv6_flowlabel {
/* Copy the flowlabel of inner packet. */
SRV6_FLOWLABEL_COPY,
/* Simply set flowlabel to 0. */
SRV6_FLOWLABEL_ZERO,
/* Set flowlabel to a hash over L3/L4 fields of the inner packet. */
SRV6_FLOWLABEL_COMPUTE,
};
enum netdev_tnl_csum {
/* Default value for UDP tunnels if no configurations is present. Enforce
* checksum calculation in IPv6 tunnels, disable in IPv4 tunnels. */
NETDEV_TNL_CSUM_DEFAULT = 0,
/* Checksum explicitly to be calculated. */
NETDEV_TNL_CSUM_ENABLED,
/* Checksum calculation explicitly disabled. */
NETDEV_TNL_CSUM_DISABLED,
/* A value for when there is no checksum or the default value is no
* checksum regardless of IP version. */
NETDEV_TNL_DEFAULT_NO_CSUM,
};
/* Configuration specific to tunnels. */
struct netdev_tunnel_config {
ovs_be64 in_key;
bool in_key_present;
bool in_key_flow;
bool out_key_present;
bool out_key_flow;
ovs_be64 out_key;
ovs_be16 payload_ethertype;
ovs_be16 dst_port;
bool ip_src_flow;
bool ip_dst_flow;
struct in6_addr ipv6_src;
struct in6_addr ipv6_dst;
uint32_t exts;
uint32_t egress_pkt_mark;
bool set_egress_pkt_mark;
uint8_t ttl;
bool ttl_inherit;
uint8_t tos;
bool tos_inherit;
enum netdev_tnl_csum csum;
bool dont_fragment;
enum netdev_pt_mode pt_mode;
bool set_seq;
uint32_t erspan_idx;
uint8_t erspan_ver;
uint8_t erspan_dir;
uint8_t erspan_hwid;
bool erspan_ver_flow;
bool erspan_idx_flow;
bool erspan_dir_flow;
bool erspan_hwid_flow;
uint8_t srv6_num_segs;
#define SRV6_MAX_SEGS 6
struct in6_addr srv6_segs[SRV6_MAX_SEGS];
enum netdev_srv6_flowlabel srv6_flowlabel;
};
void netdev_run(void);
void netdev_wait(void);
void netdev_enumerate_types(struct sset *types);
bool netdev_is_reserved_name(const char *name);
int netdev_n_txq(const struct netdev *netdev);
int netdev_n_rxq(const struct netdev *netdev);
bool netdev_is_pmd(const struct netdev *netdev);
bool netdev_has_tunnel_push_pop(const struct netdev *netdev);
/* Open and close. */
int netdev_open(const char *name, const char *type, struct netdev **netdevp);
struct netdev *netdev_ref(const struct netdev *);
void netdev_remove(struct netdev *);
void netdev_close(struct netdev *);
void netdev_parse_name(const char *netdev_name, char **name, char **type);
/* Options. */
int netdev_set_config(struct netdev *, const struct smap *args, char **errp);
int netdev_get_config(const struct netdev *, struct smap *);
const struct netdev_tunnel_config *
netdev_get_tunnel_config(const struct netdev *);
int netdev_get_numa_id(const struct netdev *);
/* Basic properties. */
const char *netdev_get_name(const struct netdev *);
const char *netdev_get_type(const struct netdev *);
const char *netdev_get_type_from_name(const char *);
int netdev_get_mtu(const struct netdev *, int *mtup);
int netdev_set_mtu(struct netdev *, int mtu);
void netdev_mtu_user_config(struct netdev *, bool);
bool netdev_mtu_is_user_config(struct netdev *);
int netdev_get_ifindex(const struct netdev *);
int netdev_set_tx_multiq(struct netdev *, unsigned int n_txq);
enum netdev_pt_mode netdev_get_pt_mode(const struct netdev *);
void netdev_set_dpif_type(struct netdev *, const char *);
const char *netdev_get_dpif_type(const struct netdev *);
/* Packet reception. */
int netdev_rxq_open(struct netdev *, struct netdev_rxq **, int id);
void netdev_rxq_close(struct netdev_rxq *);
bool netdev_rxq_enabled(struct netdev_rxq *);
const char *netdev_rxq_get_name(const struct netdev_rxq *);
int netdev_rxq_get_queue_id(const struct netdev_rxq *);
int netdev_rxq_recv(struct netdev_rxq *rx, struct dp_packet_batch *,
int *qfill);
void netdev_rxq_wait(struct netdev_rxq *);
int netdev_rxq_drain(struct netdev_rxq *);
/* Packet transmission. */
int netdev_send(struct netdev *, int qid, struct dp_packet_batch *,
bool concurrent_txq);
void netdev_send_wait(struct netdev *, int qid);
/* native tunnel APIs */
/* Structure to pass parameters required to build a tunnel header. */
struct netdev_tnl_build_header_params {
const struct flow *flow;
const struct in6_addr *s_ip;
struct eth_addr dmac;
struct eth_addr smac;
bool is_ipv6;
};
void
netdev_init_tnl_build_header_params(struct netdev_tnl_build_header_params *params,
const struct flow *tnl_flow,
const struct in6_addr *src,
struct eth_addr dmac,
struct eth_addr smac);
int netdev_build_header(const struct netdev *, struct ovs_action_push_tnl *data,
const struct netdev_tnl_build_header_params *params);
int netdev_push_header(const struct netdev *netdev,
struct dp_packet_batch *,
const struct ovs_action_push_tnl *data);
void netdev_pop_header(struct netdev *netdev, struct dp_packet_batch *);
/* Hardware address. */
int netdev_set_etheraddr(struct netdev *, const struct eth_addr mac);
int netdev_get_etheraddr(const struct netdev *, struct eth_addr *mac);
/* PHY interface. */
bool netdev_get_carrier(const struct netdev *);
long long int netdev_get_carrier_resets(const struct netdev *);
int netdev_set_miimon_interval(struct netdev *, long long int interval);
/* Flags. */
enum netdev_flags {
NETDEV_UP = 0x0001, /* Device enabled? */
NETDEV_PROMISC = 0x0002, /* Promiscuous mode? */
NETDEV_LOOPBACK = 0x0004 /* This is a loopback device. */
};
int netdev_get_flags(const struct netdev *, enum netdev_flags *);
int netdev_set_flags(struct netdev *, enum netdev_flags,
struct netdev_saved_flags **);
int netdev_turn_flags_on(struct netdev *, enum netdev_flags,
struct netdev_saved_flags **);
int netdev_turn_flags_off(struct netdev *, enum netdev_flags,
struct netdev_saved_flags **);
void netdev_restore_flags(struct netdev_saved_flags *);
/* TCP/IP stack interface. */
int netdev_set_in4(struct netdev *, struct in_addr addr, struct in_addr mask);
int netdev_get_in4_by_name(const char *device_name, struct in_addr *in4);
int netdev_get_ip_by_name(const char *device_name, struct in6_addr *);
int netdev_get_addr_list(const struct netdev *netdev, struct in6_addr **addr,
struct in6_addr **mask, int *n_in6);
int netdev_add_router(struct netdev *, struct in_addr router);
int netdev_get_next_hop(const struct netdev *, const struct in_addr *host,
struct in_addr *next_hop, char **);
int netdev_get_status(const struct netdev *, struct smap *);
int netdev_arp_lookup(const struct netdev *, ovs_be32 ip,
struct eth_addr *mac);
struct netdev *netdev_find_dev_by_in4(const struct in_addr *);
/* Statistics. */
int netdev_get_stats(const struct netdev *, struct netdev_stats *);
int netdev_get_custom_stats(const struct netdev *,
struct netdev_custom_stats *);
/* Quality of service. */
struct netdev_qos_capabilities {
unsigned int n_queues;
};
struct netdev_queue_stats {
/* Values of unsupported statistics are set to all-1-bits (UINT64_MAX). */
uint64_t tx_bytes;
uint64_t tx_packets;
uint64_t tx_errors;
/* Time at which the queue was created, in msecs, LLONG_MIN if unknown. */
long long int created;
};
int netdev_set_policing(struct netdev *, uint32_t kbits_rate,
uint32_t kbits_burst, uint32_t kpkts_rate,
uint32_t kpkts_burst);
int netdev_get_qos_types(const struct netdev *, struct sset *types);
int netdev_get_qos_capabilities(const struct netdev *,
const char *type,
struct netdev_qos_capabilities *);
int netdev_get_n_queues(const struct netdev *,
const char *type, unsigned int *n_queuesp);
int netdev_get_qos(const struct netdev *,
const char **typep, struct smap *details);
int netdev_set_qos(struct netdev *,
const char *type, const struct smap *details);
int netdev_get_queue(const struct netdev *,
unsigned int queue_id, struct smap *details);
int netdev_set_queue(struct netdev *,
unsigned int queue_id, const struct smap *details);
int netdev_delete_queue(struct netdev *, unsigned int queue_id);
int netdev_get_queue_stats(const struct netdev *, unsigned int queue_id,
struct netdev_queue_stats *);
uint64_t netdev_get_change_seq(const struct netdev *);
int netdev_reconfigure(struct netdev *netdev);
void netdev_wait_reconf_required(struct netdev *netdev);
bool netdev_is_reconf_required(struct netdev *netdev);
struct netdev_queue_dump {
struct netdev *netdev;
int error;
void *state;
};
void netdev_queue_dump_start(struct netdev_queue_dump *,
const struct netdev *);
bool netdev_queue_dump_next(struct netdev_queue_dump *,
unsigned int *queue_id, struct smap *details);
int netdev_queue_dump_done(struct netdev_queue_dump *);
/* Iterates through each queue in NETDEV, using DUMP as state. Fills QUEUE_ID
* and DETAILS with information about queues. The client must initialize and
* destroy DETAILS.
*
* Arguments all have pointer type.
*
* If you break out of the loop, then you need to free the dump structure by
* hand using netdev_queue_dump_done(). */
#define NETDEV_QUEUE_FOR_EACH(QUEUE_ID, DETAILS, DUMP, NETDEV) \
for (netdev_queue_dump_start(DUMP, NETDEV); \
(netdev_queue_dump_next(DUMP, QUEUE_ID, DETAILS) \
? true \
: (netdev_queue_dump_done(DUMP), false)); \
)
typedef void netdev_dump_queue_stats_cb(unsigned int queue_id,
struct netdev_queue_stats *,
void *aux);
int netdev_dump_queue_stats(const struct netdev *,
netdev_dump_queue_stats_cb *, void *aux);
extern struct seq *tnl_conf_seq;
#ifndef _WIN32
void netdev_get_addrs_list_flush(void);
int netdev_get_addrs(const char dev[], struct in6_addr **paddr,
struct in6_addr **pmask, int *n_in6);
#endif
#ifdef __cplusplus
}
#endif
#endif /* netdev.h */
|