2 * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "dpif-netdev.h"
24 #include <netinet/in.h>
25 #include <sys/socket.h>
30 #include <sys/ioctl.h>
34 #include "classifier.h"
38 #include "dpif-provider.h"
40 #include "dynamic-string.h"
41 #include "fat-rwlock.h"
46 #include "meta-flow.h"
48 #include "netdev-dpdk.h"
49 #include "netdev-vport.h"
51 #include "odp-execute.h"
53 #include "ofp-print.h"
56 #include "packet-dpif.h"
58 #include "poll-loop.h"
68 VLOG_DEFINE_THIS_MODULE(dpif_netdev
);
70 /* By default, choose a priority in the middle. */
71 #define NETDEV_RULE_PRIORITY 0x8000
73 #define FLOW_DUMP_MAX_BATCH 50
74 /* Use per thread recirc_depth to prevent recirculation loop. */
75 #define MAX_RECIRC_DEPTH 5
76 DEFINE_STATIC_PER_THREAD_DATA(uint32_t, recirc_depth
, 0)
78 /* Configuration parameters. */
79 enum { MAX_FLOWS
= 65536 }; /* Maximum number of flows in flow table. */
81 /* Protects against changes to 'dp_netdevs'. */
82 static struct ovs_mutex dp_netdev_mutex
= OVS_MUTEX_INITIALIZER
;
84 /* Contains all 'struct dp_netdev's. */
85 static struct shash dp_netdevs
OVS_GUARDED_BY(dp_netdev_mutex
)
86 = SHASH_INITIALIZER(&dp_netdevs
);
88 static struct vlog_rate_limit upcall_rl
= VLOG_RATE_LIMIT_INIT(600, 600);
90 /* Datapath based on the network device interface from netdev.h.
96 * Some members, marked 'const', are immutable. Accessing other members
97 * requires synchronization, as noted in more detail below.
99 * Acquisition order is, from outermost to innermost:
101 * dp_netdev_mutex (global)
106 const struct dpif_class
*const class;
107 const char *const name
;
109 struct ovs_refcount ref_cnt
;
110 atomic_flag destroyed
;
114 * Writers of 'flow_table' must take the 'flow_mutex'. Corresponding
115 * changes to 'cls' must be made while still holding the 'flow_mutex'.
117 struct ovs_mutex flow_mutex
;
118 struct classifier cls
;
119 struct cmap flow_table OVS_GUARDED
; /* Flow table. */
123 * ovsthread_stats is internally synchronized. */
124 struct ovsthread_stats stats
; /* Contains 'struct dp_netdev_stats *'. */
128 * Protected by RCU. Take the mutex to add or remove ports. */
129 struct ovs_mutex port_mutex
;
131 struct seq
*port_seq
; /* Incremented whenever a port changes. */
133 /* Protects access to ofproto-dpif-upcall interface during revalidator
134 * thread synchronization. */
135 struct fat_rwlock upcall_rwlock
;
136 upcall_callback
*upcall_cb
; /* Callback function for executing upcalls. */
139 /* Forwarding threads. */
140 struct latch exit_latch
;
141 struct pmd_thread
*pmd_threads
;
142 size_t n_pmd_threads
;
146 static struct dp_netdev_port
*dp_netdev_lookup_port(const struct dp_netdev
*dp
,
150 DP_STAT_HIT
, /* Packets that matched in the flow table. */
151 DP_STAT_MISS
, /* Packets that did not match. */
152 DP_STAT_LOST
, /* Packets not passed up to the client. */
156 /* Contained by struct dp_netdev's 'stats' member. */
157 struct dp_netdev_stats
{
158 struct ovs_mutex mutex
; /* Protects 'n'. */
160 /* Indexed by DP_STAT_*, protected by 'mutex'. */
161 unsigned long long int n
[DP_N_STATS
] OVS_GUARDED
;
165 /* A port in a netdev-based datapath. */
166 struct dp_netdev_port
{
167 struct cmap_node node
; /* Node in dp_netdev's 'ports'. */
169 struct netdev
*netdev
;
170 struct netdev_saved_flags
*sf
;
171 struct netdev_rxq
**rxq
;
172 struct ovs_refcount ref_cnt
;
173 char *type
; /* Port type as requested by user. */
177 /* Stores a miniflow */
179 /* There are fields in the flow structure that we never use. Therefore we can
180 * save a few words of memory */
181 #define NETDEV_KEY_BUF_SIZE_U32 (FLOW_U32S - MINI_N_INLINE \
182 - FLOW_U32_SIZE(regs) \
183 - FLOW_U32_SIZE(metadata) \
185 struct netdev_flow_key
{
186 struct miniflow flow
;
187 uint32_t buf
[NETDEV_KEY_BUF_SIZE_U32
];
190 /* A flow in dp_netdev's 'flow_table'.
196 * Except near the beginning or ending of its lifespan, rule 'rule' belongs to
197 * its dp_netdev's classifier. The text below calls this classifier 'cls'.
202 * The thread safety rules described here for "struct dp_netdev_flow" are
203 * motivated by two goals:
205 * - Prevent threads that read members of "struct dp_netdev_flow" from
206 * reading bad data due to changes by some thread concurrently modifying
209 * - Prevent two threads making changes to members of a given "struct
210 * dp_netdev_flow" from interfering with each other.
216 * A flow 'flow' may be accessed without a risk of being freed during an RCU
217 * grace period. Code that needs to hold onto a flow for a while
218 * should try incrementing 'flow->ref_cnt' with dp_netdev_flow_ref().
220 * 'flow->ref_cnt' protects 'flow' from being freed. It doesn't protect the
221 * flow from being deleted from 'cls' and it doesn't protect members of 'flow'
224 * Some members, marked 'const', are immutable. Accessing other members
225 * requires synchronization, as noted in more detail below.
227 struct dp_netdev_flow
{
228 /* Packet classification. */
229 const struct cls_rule cr
; /* In owning dp_netdev's 'cls'. */
231 /* Hash table index by unmasked flow. */
232 const struct cmap_node node
; /* In owning dp_netdev's 'flow_table'. */
233 const struct flow flow
; /* The flow that created this entry. */
235 /* Number of references.
236 * The classifier owns one reference.
237 * Any thread trying to keep a rule from being freed should hold its own
239 struct ovs_refcount ref_cnt
;
243 * Reading or writing these members requires 'mutex'. */
244 struct ovsthread_stats stats
; /* Contains "struct dp_netdev_flow_stats". */
247 OVSRCU_TYPE(struct dp_netdev_actions
*) actions
;
250 static void dp_netdev_flow_unref(struct dp_netdev_flow
*);
252 /* Contained by struct dp_netdev_flow's 'stats' member. */
253 struct dp_netdev_flow_stats
{
254 struct ovs_mutex mutex
; /* Guards all the other members. */
256 long long int used OVS_GUARDED
; /* Last used time, in monotonic msecs. */
257 long long int packet_count OVS_GUARDED
; /* Number of packets matched. */
258 long long int byte_count OVS_GUARDED
; /* Number of bytes matched. */
259 uint16_t tcp_flags OVS_GUARDED
; /* Bitwise-OR of seen tcp_flags values. */
262 /* A set of datapath actions within a "struct dp_netdev_flow".
268 * A struct dp_netdev_actions 'actions' is protected with RCU. */
269 struct dp_netdev_actions
{
270 /* These members are immutable: they do not change during the struct's
272 struct nlattr
*actions
; /* Sequence of OVS_ACTION_ATTR_* attributes. */
273 unsigned int size
; /* Size of 'actions', in bytes. */
276 struct dp_netdev_actions
*dp_netdev_actions_create(const struct nlattr
*,
278 struct dp_netdev_actions
*dp_netdev_flow_get_actions(
279 const struct dp_netdev_flow
*);
280 static void dp_netdev_actions_free(struct dp_netdev_actions
*);
282 /* PMD: Poll modes drivers. PMD accesses devices via polling to eliminate
283 * the performance overhead of interrupt processing. Therefore netdev can
284 * not implement rx-wait for these devices. dpif-netdev needs to poll
285 * these device to check for recv buffer. pmd-thread does polling for
286 * devices assigned to itself thread.
288 * DPDK used PMD for accessing NIC.
290 * A thread that receives packets from PMD ports, looks them up in the flow
291 * table, and executes the actions it finds.
294 struct dp_netdev
*dp
;
297 atomic_uint change_seq
;
300 #define PMD_INITIAL_SEQ 1
302 /* Interface to netdev-based datapath. */
305 struct dp_netdev
*dp
;
306 uint64_t last_port_seq
;
309 static int get_port_by_number(struct dp_netdev
*dp
, odp_port_t port_no
,
310 struct dp_netdev_port
**portp
);
311 static int get_port_by_name(struct dp_netdev
*dp
, const char *devname
,
312 struct dp_netdev_port
**portp
);
313 static void dp_netdev_free(struct dp_netdev
*)
314 OVS_REQUIRES(dp_netdev_mutex
);
315 static void dp_netdev_flow_flush(struct dp_netdev
*);
316 static int do_add_port(struct dp_netdev
*dp
, const char *devname
,
317 const char *type
, odp_port_t port_no
)
318 OVS_REQUIRES(dp
->port_mutex
);
319 static void do_del_port(struct dp_netdev
*dp
, struct dp_netdev_port
*)
320 OVS_REQUIRES(dp
->port_mutex
);
321 static int dpif_netdev_open(const struct dpif_class
*, const char *name
,
322 bool create
, struct dpif
**);
323 static void dp_netdev_execute_actions(struct dp_netdev
*dp
,
324 struct dpif_packet
**, int c
,
325 bool may_steal
, struct pkt_metadata
*,
326 const struct nlattr
*actions
,
328 static void dp_netdev_port_input(struct dp_netdev
*dp
,
329 struct dpif_packet
**packets
, int cnt
,
332 static void dp_netdev_set_pmd_threads(struct dp_netdev
*, int n
);
333 static void dp_netdev_disable_upcall(struct dp_netdev
*);
335 static struct dpif_netdev
*
336 dpif_netdev_cast(const struct dpif
*dpif
)
338 ovs_assert(dpif
->dpif_class
->open
== dpif_netdev_open
);
339 return CONTAINER_OF(dpif
, struct dpif_netdev
, dpif
);
342 static struct dp_netdev
*
343 get_dp_netdev(const struct dpif
*dpif
)
345 return dpif_netdev_cast(dpif
)->dp
;
349 dpif_netdev_enumerate(struct sset
*all_dps
,
350 const struct dpif_class
*dpif_class
)
352 struct shash_node
*node
;
354 ovs_mutex_lock(&dp_netdev_mutex
);
355 SHASH_FOR_EACH(node
, &dp_netdevs
) {
356 struct dp_netdev
*dp
= node
->data
;
357 if (dpif_class
!= dp
->class) {
358 /* 'dp_netdevs' contains both "netdev" and "dummy" dpifs.
359 * If the class doesn't match, skip this dpif. */
362 sset_add(all_dps
, node
->name
);
364 ovs_mutex_unlock(&dp_netdev_mutex
);
370 dpif_netdev_class_is_dummy(const struct dpif_class
*class)
372 return class != &dpif_netdev_class
;
376 dpif_netdev_port_open_type(const struct dpif_class
*class, const char *type
)
378 return strcmp(type
, "internal") ? type
379 : dpif_netdev_class_is_dummy(class) ? "dummy"
384 create_dpif_netdev(struct dp_netdev
*dp
)
386 uint16_t netflow_id
= hash_string(dp
->name
, 0);
387 struct dpif_netdev
*dpif
;
389 ovs_refcount_ref(&dp
->ref_cnt
);
391 dpif
= xmalloc(sizeof *dpif
);
392 dpif_init(&dpif
->dpif
, dp
->class, dp
->name
, netflow_id
>> 8, netflow_id
);
394 dpif
->last_port_seq
= seq_read(dp
->port_seq
);
399 /* Choose an unused, non-zero port number and return it on success.
400 * Return ODPP_NONE on failure. */
402 choose_port(struct dp_netdev
*dp
, const char *name
)
403 OVS_REQUIRES(dp
->port_mutex
)
407 if (dp
->class != &dpif_netdev_class
) {
411 /* If the port name begins with "br", start the number search at
412 * 100 to make writing tests easier. */
413 if (!strncmp(name
, "br", 2)) {
417 /* If the port name contains a number, try to assign that port number.
418 * This can make writing unit tests easier because port numbers are
420 for (p
= name
; *p
!= '\0'; p
++) {
421 if (isdigit((unsigned char) *p
)) {
422 port_no
= start_no
+ strtol(p
, NULL
, 10);
423 if (port_no
> 0 && port_no
!= odp_to_u32(ODPP_NONE
)
424 && !dp_netdev_lookup_port(dp
, u32_to_odp(port_no
))) {
425 return u32_to_odp(port_no
);
432 for (port_no
= 1; port_no
<= UINT16_MAX
; port_no
++) {
433 if (!dp_netdev_lookup_port(dp
, u32_to_odp(port_no
))) {
434 return u32_to_odp(port_no
);
442 create_dp_netdev(const char *name
, const struct dpif_class
*class,
443 struct dp_netdev
**dpp
)
444 OVS_REQUIRES(dp_netdev_mutex
)
446 struct dp_netdev
*dp
;
449 dp
= xzalloc(sizeof *dp
);
450 shash_add(&dp_netdevs
, name
, dp
);
452 *CONST_CAST(const struct dpif_class
**, &dp
->class) = class;
453 *CONST_CAST(const char **, &dp
->name
) = xstrdup(name
);
454 ovs_refcount_init(&dp
->ref_cnt
);
455 atomic_flag_clear(&dp
->destroyed
);
457 ovs_mutex_init(&dp
->flow_mutex
);
458 classifier_init(&dp
->cls
, NULL
);
459 cmap_init(&dp
->flow_table
);
461 ovsthread_stats_init(&dp
->stats
);
463 ovs_mutex_init(&dp
->port_mutex
);
464 cmap_init(&dp
->ports
);
465 dp
->port_seq
= seq_create();
466 latch_init(&dp
->exit_latch
);
467 fat_rwlock_init(&dp
->upcall_rwlock
);
469 /* Disable upcalls by default. */
470 dp_netdev_disable_upcall(dp
);
471 dp
->upcall_aux
= NULL
;
472 dp
->upcall_cb
= NULL
;
474 ovs_mutex_lock(&dp
->port_mutex
);
475 error
= do_add_port(dp
, name
, "internal", ODPP_LOCAL
);
476 ovs_mutex_unlock(&dp
->port_mutex
);
487 dpif_netdev_open(const struct dpif_class
*class, const char *name
,
488 bool create
, struct dpif
**dpifp
)
490 struct dp_netdev
*dp
;
493 ovs_mutex_lock(&dp_netdev_mutex
);
494 dp
= shash_find_data(&dp_netdevs
, name
);
496 error
= create
? create_dp_netdev(name
, class, &dp
) : ENODEV
;
498 error
= (dp
->class != class ? EINVAL
503 *dpifp
= create_dpif_netdev(dp
);
506 ovs_mutex_unlock(&dp_netdev_mutex
);
511 /* Requires dp_netdev_mutex so that we can't get a new reference to 'dp'
512 * through the 'dp_netdevs' shash while freeing 'dp'. */
514 dp_netdev_free(struct dp_netdev
*dp
)
515 OVS_REQUIRES(dp_netdev_mutex
)
517 struct dp_netdev_port
*port
;
518 struct dp_netdev_stats
*bucket
;
521 shash_find_and_delete(&dp_netdevs
, dp
->name
);
523 dp_netdev_set_pmd_threads(dp
, 0);
524 free(dp
->pmd_threads
);
526 dp_netdev_flow_flush(dp
);
527 ovs_mutex_lock(&dp
->port_mutex
);
528 CMAP_FOR_EACH (port
, node
, &dp
->ports
) {
529 do_del_port(dp
, port
);
531 ovs_mutex_unlock(&dp
->port_mutex
);
533 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &dp
->stats
) {
534 ovs_mutex_destroy(&bucket
->mutex
);
535 free_cacheline(bucket
);
537 ovsthread_stats_destroy(&dp
->stats
);
539 classifier_destroy(&dp
->cls
);
540 cmap_destroy(&dp
->flow_table
);
541 ovs_mutex_destroy(&dp
->flow_mutex
);
542 seq_destroy(dp
->port_seq
);
543 cmap_destroy(&dp
->ports
);
544 fat_rwlock_destroy(&dp
->upcall_rwlock
);
545 latch_destroy(&dp
->exit_latch
);
546 free(CONST_CAST(char *, dp
->name
));
551 dp_netdev_unref(struct dp_netdev
*dp
)
554 /* Take dp_netdev_mutex so that, if dp->ref_cnt falls to zero, we can't
555 * get a new reference to 'dp' through the 'dp_netdevs' shash. */
556 ovs_mutex_lock(&dp_netdev_mutex
);
557 if (ovs_refcount_unref_relaxed(&dp
->ref_cnt
) == 1) {
560 ovs_mutex_unlock(&dp_netdev_mutex
);
565 dpif_netdev_close(struct dpif
*dpif
)
567 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
574 dpif_netdev_destroy(struct dpif
*dpif
)
576 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
578 if (!atomic_flag_test_and_set(&dp
->destroyed
)) {
579 if (ovs_refcount_unref_relaxed(&dp
->ref_cnt
) == 1) {
580 /* Can't happen: 'dpif' still owns a reference to 'dp'. */
589 dpif_netdev_get_stats(const struct dpif
*dpif
, struct dpif_dp_stats
*stats
)
591 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
592 struct dp_netdev_stats
*bucket
;
595 stats
->n_flows
= cmap_count(&dp
->flow_table
);
597 stats
->n_hit
= stats
->n_missed
= stats
->n_lost
= 0;
598 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &dp
->stats
) {
599 ovs_mutex_lock(&bucket
->mutex
);
600 stats
->n_hit
+= bucket
->n
[DP_STAT_HIT
];
601 stats
->n_missed
+= bucket
->n
[DP_STAT_MISS
];
602 stats
->n_lost
+= bucket
->n
[DP_STAT_LOST
];
603 ovs_mutex_unlock(&bucket
->mutex
);
605 stats
->n_masks
= UINT32_MAX
;
606 stats
->n_mask_hit
= UINT64_MAX
;
612 dp_netdev_reload_pmd_threads(struct dp_netdev
*dp
)
616 for (i
= 0; i
< dp
->n_pmd_threads
; i
++) {
617 struct pmd_thread
*f
= &dp
->pmd_threads
[i
];
620 atomic_add_relaxed(&f
->change_seq
, 1, &old_seq
);
625 hash_port_no(odp_port_t port_no
)
627 return hash_int(odp_to_u32(port_no
), 0);
631 do_add_port(struct dp_netdev
*dp
, const char *devname
, const char *type
,
633 OVS_REQUIRES(dp
->port_mutex
)
635 struct netdev_saved_flags
*sf
;
636 struct dp_netdev_port
*port
;
637 struct netdev
*netdev
;
638 enum netdev_flags flags
;
639 const char *open_type
;
643 /* XXX reject devices already in some dp_netdev. */
645 /* Open and validate network device. */
646 open_type
= dpif_netdev_port_open_type(dp
->class, type
);
647 error
= netdev_open(devname
, open_type
, &netdev
);
651 /* XXX reject non-Ethernet devices */
653 netdev_get_flags(netdev
, &flags
);
654 if (flags
& NETDEV_LOOPBACK
) {
655 VLOG_ERR("%s: cannot add a loopback device", devname
);
656 netdev_close(netdev
);
660 port
= xzalloc(sizeof *port
);
661 port
->port_no
= port_no
;
662 port
->netdev
= netdev
;
663 port
->rxq
= xmalloc(sizeof *port
->rxq
* netdev_n_rxq(netdev
));
664 port
->type
= xstrdup(type
);
665 for (i
= 0; i
< netdev_n_rxq(netdev
); i
++) {
666 error
= netdev_rxq_open(netdev
, &port
->rxq
[i
], i
);
668 && !(error
== EOPNOTSUPP
&& dpif_netdev_class_is_dummy(dp
->class))) {
669 VLOG_ERR("%s: cannot receive packets on this network device (%s)",
670 devname
, ovs_strerror(errno
));
671 netdev_close(netdev
);
679 error
= netdev_turn_flags_on(netdev
, NETDEV_PROMISC
, &sf
);
681 for (i
= 0; i
< netdev_n_rxq(netdev
); i
++) {
682 netdev_rxq_close(port
->rxq
[i
]);
684 netdev_close(netdev
);
692 if (netdev_is_pmd(netdev
)) {
694 dp_netdev_set_pmd_threads(dp
, NR_PMD_THREADS
);
695 dp_netdev_reload_pmd_threads(dp
);
697 ovs_refcount_init(&port
->ref_cnt
);
699 cmap_insert(&dp
->ports
, &port
->node
, hash_port_no(port_no
));
700 seq_change(dp
->port_seq
);
706 dpif_netdev_port_add(struct dpif
*dpif
, struct netdev
*netdev
,
707 odp_port_t
*port_nop
)
709 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
710 char namebuf
[NETDEV_VPORT_NAME_BUFSIZE
];
711 const char *dpif_port
;
715 ovs_mutex_lock(&dp
->port_mutex
);
716 dpif_port
= netdev_vport_get_dpif_port(netdev
, namebuf
, sizeof namebuf
);
717 if (*port_nop
!= ODPP_NONE
) {
719 error
= dp_netdev_lookup_port(dp
, *port_nop
) ? EBUSY
: 0;
721 port_no
= choose_port(dp
, dpif_port
);
722 error
= port_no
== ODPP_NONE
? EFBIG
: 0;
726 error
= do_add_port(dp
, dpif_port
, netdev_get_type(netdev
), port_no
);
728 ovs_mutex_unlock(&dp
->port_mutex
);
734 dpif_netdev_port_del(struct dpif
*dpif
, odp_port_t port_no
)
736 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
739 ovs_mutex_lock(&dp
->port_mutex
);
740 if (port_no
== ODPP_LOCAL
) {
743 struct dp_netdev_port
*port
;
745 error
= get_port_by_number(dp
, port_no
, &port
);
747 do_del_port(dp
, port
);
750 ovs_mutex_unlock(&dp
->port_mutex
);
756 is_valid_port_number(odp_port_t port_no
)
758 return port_no
!= ODPP_NONE
;
761 static struct dp_netdev_port
*
762 dp_netdev_lookup_port(const struct dp_netdev
*dp
, odp_port_t port_no
)
764 struct dp_netdev_port
*port
;
766 CMAP_FOR_EACH_WITH_HASH (port
, node
, hash_port_no(port_no
), &dp
->ports
) {
767 if (port
->port_no
== port_no
) {
775 get_port_by_number(struct dp_netdev
*dp
,
776 odp_port_t port_no
, struct dp_netdev_port
**portp
)
778 if (!is_valid_port_number(port_no
)) {
782 *portp
= dp_netdev_lookup_port(dp
, port_no
);
783 return *portp
? 0 : ENOENT
;
788 port_ref(struct dp_netdev_port
*port
)
791 ovs_refcount_ref(&port
->ref_cnt
);
796 port_destroy__(struct dp_netdev_port
*port
)
798 int n_rxq
= netdev_n_rxq(port
->netdev
);
801 netdev_close(port
->netdev
);
802 netdev_restore_flags(port
->sf
);
804 for (i
= 0; i
< n_rxq
; i
++) {
805 netdev_rxq_close(port
->rxq
[i
]);
813 port_unref(struct dp_netdev_port
*port
)
815 if (port
&& ovs_refcount_unref_relaxed(&port
->ref_cnt
) == 1) {
816 ovsrcu_postpone(port_destroy__
, port
);
821 get_port_by_name(struct dp_netdev
*dp
,
822 const char *devname
, struct dp_netdev_port
**portp
)
823 OVS_REQUIRES(dp
->port_mutex
)
825 struct dp_netdev_port
*port
;
827 CMAP_FOR_EACH (port
, node
, &dp
->ports
) {
828 if (!strcmp(netdev_get_name(port
->netdev
), devname
)) {
837 do_del_port(struct dp_netdev
*dp
, struct dp_netdev_port
*port
)
838 OVS_REQUIRES(dp
->port_mutex
)
840 cmap_remove(&dp
->ports
, &port
->node
, hash_odp_port(port
->port_no
));
841 seq_change(dp
->port_seq
);
842 if (netdev_is_pmd(port
->netdev
)) {
843 dp_netdev_reload_pmd_threads(dp
);
850 answer_port_query(const struct dp_netdev_port
*port
,
851 struct dpif_port
*dpif_port
)
853 dpif_port
->name
= xstrdup(netdev_get_name(port
->netdev
));
854 dpif_port
->type
= xstrdup(port
->type
);
855 dpif_port
->port_no
= port
->port_no
;
859 dpif_netdev_port_query_by_number(const struct dpif
*dpif
, odp_port_t port_no
,
860 struct dpif_port
*dpif_port
)
862 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
863 struct dp_netdev_port
*port
;
866 error
= get_port_by_number(dp
, port_no
, &port
);
867 if (!error
&& dpif_port
) {
868 answer_port_query(port
, dpif_port
);
875 dpif_netdev_port_query_by_name(const struct dpif
*dpif
, const char *devname
,
876 struct dpif_port
*dpif_port
)
878 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
879 struct dp_netdev_port
*port
;
882 ovs_mutex_lock(&dp
->port_mutex
);
883 error
= get_port_by_name(dp
, devname
, &port
);
884 if (!error
&& dpif_port
) {
885 answer_port_query(port
, dpif_port
);
887 ovs_mutex_unlock(&dp
->port_mutex
);
893 dp_netdev_flow_free(struct dp_netdev_flow
*flow
)
895 struct dp_netdev_flow_stats
*bucket
;
898 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &flow
->stats
) {
899 ovs_mutex_destroy(&bucket
->mutex
);
900 free_cacheline(bucket
);
902 ovsthread_stats_destroy(&flow
->stats
);
904 cls_rule_destroy(CONST_CAST(struct cls_rule
*, &flow
->cr
));
905 dp_netdev_actions_free(dp_netdev_flow_get_actions(flow
));
909 static void dp_netdev_flow_unref(struct dp_netdev_flow
*flow
)
911 if (ovs_refcount_unref_relaxed(&flow
->ref_cnt
) == 1) {
912 ovsrcu_postpone(dp_netdev_flow_free
, flow
);
917 dp_netdev_remove_flow(struct dp_netdev
*dp
, struct dp_netdev_flow
*flow
)
918 OVS_REQUIRES(dp
->flow_mutex
)
920 struct cls_rule
*cr
= CONST_CAST(struct cls_rule
*, &flow
->cr
);
921 struct cmap_node
*node
= CONST_CAST(struct cmap_node
*, &flow
->node
);
923 classifier_remove(&dp
->cls
, cr
);
924 cmap_remove(&dp
->flow_table
, node
, flow_hash(&flow
->flow
, 0));
926 dp_netdev_flow_unref(flow
);
930 dp_netdev_flow_flush(struct dp_netdev
*dp
)
932 struct dp_netdev_flow
*netdev_flow
;
934 ovs_mutex_lock(&dp
->flow_mutex
);
935 CMAP_FOR_EACH (netdev_flow
, node
, &dp
->flow_table
) {
936 dp_netdev_remove_flow(dp
, netdev_flow
);
938 ovs_mutex_unlock(&dp
->flow_mutex
);
942 dpif_netdev_flow_flush(struct dpif
*dpif
)
944 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
946 dp_netdev_flow_flush(dp
);
950 struct dp_netdev_port_state
{
951 struct cmap_position position
;
956 dpif_netdev_port_dump_start(const struct dpif
*dpif OVS_UNUSED
, void **statep
)
958 *statep
= xzalloc(sizeof(struct dp_netdev_port_state
));
963 dpif_netdev_port_dump_next(const struct dpif
*dpif
, void *state_
,
964 struct dpif_port
*dpif_port
)
966 struct dp_netdev_port_state
*state
= state_
;
967 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
968 struct cmap_node
*node
;
971 node
= cmap_next_position(&dp
->ports
, &state
->position
);
973 struct dp_netdev_port
*port
;
975 port
= CONTAINER_OF(node
, struct dp_netdev_port
, node
);
978 state
->name
= xstrdup(netdev_get_name(port
->netdev
));
979 dpif_port
->name
= state
->name
;
980 dpif_port
->type
= port
->type
;
981 dpif_port
->port_no
= port
->port_no
;
992 dpif_netdev_port_dump_done(const struct dpif
*dpif OVS_UNUSED
, void *state_
)
994 struct dp_netdev_port_state
*state
= state_
;
1001 dpif_netdev_port_poll(const struct dpif
*dpif_
, char **devnamep OVS_UNUSED
)
1003 struct dpif_netdev
*dpif
= dpif_netdev_cast(dpif_
);
1004 uint64_t new_port_seq
;
1007 new_port_seq
= seq_read(dpif
->dp
->port_seq
);
1008 if (dpif
->last_port_seq
!= new_port_seq
) {
1009 dpif
->last_port_seq
= new_port_seq
;
1019 dpif_netdev_port_poll_wait(const struct dpif
*dpif_
)
1021 struct dpif_netdev
*dpif
= dpif_netdev_cast(dpif_
);
1023 seq_wait(dpif
->dp
->port_seq
, dpif
->last_port_seq
);
1026 static struct dp_netdev_flow
*
1027 dp_netdev_flow_cast(const struct cls_rule
*cr
)
1029 return cr
? CONTAINER_OF(cr
, struct dp_netdev_flow
, cr
) : NULL
;
1032 static struct dp_netdev_flow
*
1033 dp_netdev_lookup_flow(const struct dp_netdev
*dp
, const struct miniflow
*key
)
1035 struct dp_netdev_flow
*netdev_flow
;
1036 struct cls_rule
*rule
;
1038 classifier_lookup_miniflow_batch(&dp
->cls
, &key
, &rule
, 1);
1039 netdev_flow
= dp_netdev_flow_cast(rule
);
1044 static struct dp_netdev_flow
*
1045 dp_netdev_find_flow(const struct dp_netdev
*dp
, const struct flow
*flow
)
1047 struct dp_netdev_flow
*netdev_flow
;
1049 CMAP_FOR_EACH_WITH_HASH (netdev_flow
, node
, flow_hash(flow
, 0),
1051 if (flow_equal(&netdev_flow
->flow
, flow
)) {
1060 get_dpif_flow_stats(const struct dp_netdev_flow
*netdev_flow
,
1061 struct dpif_flow_stats
*stats
)
1063 struct dp_netdev_flow_stats
*bucket
;
1066 memset(stats
, 0, sizeof *stats
);
1067 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &netdev_flow
->stats
) {
1068 ovs_mutex_lock(&bucket
->mutex
);
1069 stats
->n_packets
+= bucket
->packet_count
;
1070 stats
->n_bytes
+= bucket
->byte_count
;
1071 stats
->used
= MAX(stats
->used
, bucket
->used
);
1072 stats
->tcp_flags
|= bucket
->tcp_flags
;
1073 ovs_mutex_unlock(&bucket
->mutex
);
1078 dp_netdev_flow_to_dpif_flow(const struct dp_netdev_flow
*netdev_flow
,
1079 struct ofpbuf
*buffer
, struct dpif_flow
*flow
)
1081 struct flow_wildcards wc
;
1082 struct dp_netdev_actions
*actions
;
1084 minimask_expand(&netdev_flow
->cr
.match
.mask
, &wc
);
1085 odp_flow_key_from_mask(buffer
, &wc
.masks
, &netdev_flow
->flow
,
1086 odp_to_u32(wc
.masks
.in_port
.odp_port
),
1088 flow
->mask
= ofpbuf_data(buffer
);
1089 flow
->mask_len
= ofpbuf_size(buffer
);
1091 actions
= dp_netdev_flow_get_actions(netdev_flow
);
1092 flow
->actions
= actions
->actions
;
1093 flow
->actions_len
= actions
->size
;
1095 get_dpif_flow_stats(netdev_flow
, &flow
->stats
);
1099 dpif_netdev_mask_from_nlattrs(const struct nlattr
*key
, uint32_t key_len
,
1100 const struct nlattr
*mask_key
,
1101 uint32_t mask_key_len
, const struct flow
*flow
,
1105 enum odp_key_fitness fitness
;
1107 fitness
= odp_flow_key_to_mask(mask_key
, mask_key_len
, mask
, flow
);
1109 /* This should not happen: it indicates that
1110 * odp_flow_key_from_mask() and odp_flow_key_to_mask()
1111 * disagree on the acceptable form of a mask. Log the problem
1112 * as an error, with enough details to enable debugging. */
1113 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
1115 if (!VLOG_DROP_ERR(&rl
)) {
1119 odp_flow_format(key
, key_len
, mask_key
, mask_key_len
, NULL
, &s
,
1121 VLOG_ERR("internal error parsing flow mask %s (%s)",
1122 ds_cstr(&s
), odp_key_fitness_to_string(fitness
));
1129 enum mf_field_id id
;
1130 /* No mask key, unwildcard everything except fields whose
1131 * prerequisities are not met. */
1132 memset(mask
, 0x0, sizeof *mask
);
1134 for (id
= 0; id
< MFF_N_IDS
; ++id
) {
1135 /* Skip registers and metadata. */
1136 if (!(id
>= MFF_REG0
&& id
< MFF_REG0
+ FLOW_N_REGS
)
1137 && id
!= MFF_METADATA
) {
1138 const struct mf_field
*mf
= mf_from_id(id
);
1139 if (mf_are_prereqs_ok(mf
, flow
)) {
1140 mf_mask_field(mf
, mask
);
1146 /* Force unwildcard the in_port.
1148 * We need to do this even in the case where we unwildcard "everything"
1149 * above because "everything" only includes the 16-bit OpenFlow port number
1150 * mask->in_port.ofp_port, which only covers half of the 32-bit datapath
1151 * port number mask->in_port.odp_port. */
1152 mask
->in_port
.odp_port
= u32_to_odp(UINT32_MAX
);
1158 dpif_netdev_flow_from_nlattrs(const struct nlattr
*key
, uint32_t key_len
,
1163 if (odp_flow_key_to_flow(key
, key_len
, flow
)) {
1164 /* This should not happen: it indicates that odp_flow_key_from_flow()
1165 * and odp_flow_key_to_flow() disagree on the acceptable form of a
1166 * flow. Log the problem as an error, with enough details to enable
1168 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
1170 if (!VLOG_DROP_ERR(&rl
)) {
1174 odp_flow_format(key
, key_len
, NULL
, 0, NULL
, &s
, true);
1175 VLOG_ERR("internal error parsing flow key %s", ds_cstr(&s
));
1182 in_port
= flow
->in_port
.odp_port
;
1183 if (!is_valid_port_number(in_port
) && in_port
!= ODPP_NONE
) {
1191 dpif_netdev_flow_get(const struct dpif
*dpif
, const struct dpif_flow_get
*get
)
1193 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1194 struct dp_netdev_flow
*netdev_flow
;
1198 error
= dpif_netdev_flow_from_nlattrs(get
->key
, get
->key_len
, &key
);
1203 netdev_flow
= dp_netdev_find_flow(dp
, &key
);
1206 dp_netdev_flow_to_dpif_flow(netdev_flow
, get
->buffer
, get
->flow
);
1215 dp_netdev_flow_add(struct dp_netdev
*dp
, struct match
*match
,
1216 const struct nlattr
*actions
, size_t actions_len
)
1217 OVS_REQUIRES(dp
->flow_mutex
)
1219 struct dp_netdev_flow
*netdev_flow
;
1221 netdev_flow
= xzalloc(sizeof *netdev_flow
);
1222 *CONST_CAST(struct flow
*, &netdev_flow
->flow
) = match
->flow
;
1224 ovs_refcount_init(&netdev_flow
->ref_cnt
);
1226 ovsthread_stats_init(&netdev_flow
->stats
);
1228 ovsrcu_set(&netdev_flow
->actions
,
1229 dp_netdev_actions_create(actions
, actions_len
));
1231 cls_rule_init(CONST_CAST(struct cls_rule
*, &netdev_flow
->cr
),
1232 match
, NETDEV_RULE_PRIORITY
);
1233 cmap_insert(&dp
->flow_table
,
1234 CONST_CAST(struct cmap_node
*, &netdev_flow
->node
),
1235 flow_hash(&match
->flow
, 0));
1236 classifier_insert(&dp
->cls
,
1237 CONST_CAST(struct cls_rule
*, &netdev_flow
->cr
));
1239 if (OVS_UNLIKELY(VLOG_IS_DBG_ENABLED())) {
1240 struct ds ds
= DS_EMPTY_INITIALIZER
;
1242 ds_put_cstr(&ds
, "flow_add: ");
1243 match_format(match
, &ds
, OFP_DEFAULT_PRIORITY
);
1244 ds_put_cstr(&ds
, ", actions:");
1245 format_odp_actions(&ds
, actions
, actions_len
);
1247 VLOG_DBG_RL(&upcall_rl
, "%s", ds_cstr(&ds
));
1256 clear_stats(struct dp_netdev_flow
*netdev_flow
)
1258 struct dp_netdev_flow_stats
*bucket
;
1261 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &netdev_flow
->stats
) {
1262 ovs_mutex_lock(&bucket
->mutex
);
1264 bucket
->packet_count
= 0;
1265 bucket
->byte_count
= 0;
1266 bucket
->tcp_flags
= 0;
1267 ovs_mutex_unlock(&bucket
->mutex
);
1272 dpif_netdev_flow_put(struct dpif
*dpif
, const struct dpif_flow_put
*put
)
1274 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1275 struct dp_netdev_flow
*netdev_flow
;
1276 struct miniflow miniflow
;
1280 error
= dpif_netdev_flow_from_nlattrs(put
->key
, put
->key_len
, &match
.flow
);
1284 error
= dpif_netdev_mask_from_nlattrs(put
->key
, put
->key_len
,
1285 put
->mask
, put
->mask_len
,
1286 &match
.flow
, &match
.wc
.masks
);
1290 miniflow_init(&miniflow
, &match
.flow
);
1292 ovs_mutex_lock(&dp
->flow_mutex
);
1293 netdev_flow
= dp_netdev_lookup_flow(dp
, &miniflow
);
1295 if (put
->flags
& DPIF_FP_CREATE
) {
1296 if (cmap_count(&dp
->flow_table
) < MAX_FLOWS
) {
1298 memset(put
->stats
, 0, sizeof *put
->stats
);
1300 error
= dp_netdev_flow_add(dp
, &match
, put
->actions
,
1309 if (put
->flags
& DPIF_FP_MODIFY
1310 && flow_equal(&match
.flow
, &netdev_flow
->flow
)) {
1311 struct dp_netdev_actions
*new_actions
;
1312 struct dp_netdev_actions
*old_actions
;
1314 new_actions
= dp_netdev_actions_create(put
->actions
,
1317 old_actions
= dp_netdev_flow_get_actions(netdev_flow
);
1318 ovsrcu_set(&netdev_flow
->actions
, new_actions
);
1321 get_dpif_flow_stats(netdev_flow
, put
->stats
);
1323 if (put
->flags
& DPIF_FP_ZERO_STATS
) {
1324 clear_stats(netdev_flow
);
1327 ovsrcu_postpone(dp_netdev_actions_free
, old_actions
);
1328 } else if (put
->flags
& DPIF_FP_CREATE
) {
1331 /* Overlapping flow. */
1335 ovs_mutex_unlock(&dp
->flow_mutex
);
1336 miniflow_destroy(&miniflow
);
1342 dpif_netdev_flow_del(struct dpif
*dpif
, const struct dpif_flow_del
*del
)
1344 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1345 struct dp_netdev_flow
*netdev_flow
;
1349 error
= dpif_netdev_flow_from_nlattrs(del
->key
, del
->key_len
, &key
);
1354 ovs_mutex_lock(&dp
->flow_mutex
);
1355 netdev_flow
= dp_netdev_find_flow(dp
, &key
);
1358 get_dpif_flow_stats(netdev_flow
, del
->stats
);
1360 dp_netdev_remove_flow(dp
, netdev_flow
);
1364 ovs_mutex_unlock(&dp
->flow_mutex
);
1369 struct dpif_netdev_flow_dump
{
1370 struct dpif_flow_dump up
;
1371 struct cmap_position pos
;
1373 struct ovs_mutex mutex
;
1376 static struct dpif_netdev_flow_dump
*
1377 dpif_netdev_flow_dump_cast(struct dpif_flow_dump
*dump
)
1379 return CONTAINER_OF(dump
, struct dpif_netdev_flow_dump
, up
);
1382 static struct dpif_flow_dump
*
1383 dpif_netdev_flow_dump_create(const struct dpif
*dpif_
)
1385 struct dpif_netdev_flow_dump
*dump
;
1387 dump
= xmalloc(sizeof *dump
);
1388 dpif_flow_dump_init(&dump
->up
, dpif_
);
1389 memset(&dump
->pos
, 0, sizeof dump
->pos
);
1391 ovs_mutex_init(&dump
->mutex
);
1397 dpif_netdev_flow_dump_destroy(struct dpif_flow_dump
*dump_
)
1399 struct dpif_netdev_flow_dump
*dump
= dpif_netdev_flow_dump_cast(dump_
);
1401 ovs_mutex_destroy(&dump
->mutex
);
1406 struct dpif_netdev_flow_dump_thread
{
1407 struct dpif_flow_dump_thread up
;
1408 struct dpif_netdev_flow_dump
*dump
;
1409 struct odputil_keybuf keybuf
[FLOW_DUMP_MAX_BATCH
];
1410 struct odputil_keybuf maskbuf
[FLOW_DUMP_MAX_BATCH
];
1413 static struct dpif_netdev_flow_dump_thread
*
1414 dpif_netdev_flow_dump_thread_cast(struct dpif_flow_dump_thread
*thread
)
1416 return CONTAINER_OF(thread
, struct dpif_netdev_flow_dump_thread
, up
);
1419 static struct dpif_flow_dump_thread
*
1420 dpif_netdev_flow_dump_thread_create(struct dpif_flow_dump
*dump_
)
1422 struct dpif_netdev_flow_dump
*dump
= dpif_netdev_flow_dump_cast(dump_
);
1423 struct dpif_netdev_flow_dump_thread
*thread
;
1425 thread
= xmalloc(sizeof *thread
);
1426 dpif_flow_dump_thread_init(&thread
->up
, &dump
->up
);
1427 thread
->dump
= dump
;
1432 dpif_netdev_flow_dump_thread_destroy(struct dpif_flow_dump_thread
*thread_
)
1434 struct dpif_netdev_flow_dump_thread
*thread
1435 = dpif_netdev_flow_dump_thread_cast(thread_
);
1441 dpif_netdev_flow_dump_next(struct dpif_flow_dump_thread
*thread_
,
1442 struct dpif_flow
*flows
, int max_flows
)
1444 struct dpif_netdev_flow_dump_thread
*thread
1445 = dpif_netdev_flow_dump_thread_cast(thread_
);
1446 struct dpif_netdev_flow_dump
*dump
= thread
->dump
;
1447 struct dpif_netdev
*dpif
= dpif_netdev_cast(thread
->up
.dpif
);
1448 struct dp_netdev_flow
*netdev_flows
[FLOW_DUMP_MAX_BATCH
];
1449 struct dp_netdev
*dp
= get_dp_netdev(&dpif
->dpif
);
1453 ovs_mutex_lock(&dump
->mutex
);
1454 if (!dump
->status
) {
1455 for (n_flows
= 0; n_flows
< MIN(max_flows
, FLOW_DUMP_MAX_BATCH
);
1457 struct cmap_node
*node
;
1459 node
= cmap_next_position(&dp
->flow_table
, &dump
->pos
);
1464 netdev_flows
[n_flows
] = CONTAINER_OF(node
, struct dp_netdev_flow
,
1468 ovs_mutex_unlock(&dump
->mutex
);
1470 for (i
= 0; i
< n_flows
; i
++) {
1471 struct odputil_keybuf
*maskbuf
= &thread
->maskbuf
[i
];
1472 struct odputil_keybuf
*keybuf
= &thread
->keybuf
[i
];
1473 struct dp_netdev_flow
*netdev_flow
= netdev_flows
[i
];
1474 struct dpif_flow
*f
= &flows
[i
];
1475 struct dp_netdev_actions
*dp_actions
;
1476 struct flow_wildcards wc
;
1479 minimask_expand(&netdev_flow
->cr
.match
.mask
, &wc
);
1482 ofpbuf_use_stack(&buf
, keybuf
, sizeof *keybuf
);
1483 odp_flow_key_from_flow(&buf
, &netdev_flow
->flow
, &wc
.masks
,
1484 netdev_flow
->flow
.in_port
.odp_port
, true);
1485 f
->key
= ofpbuf_data(&buf
);
1486 f
->key_len
= ofpbuf_size(&buf
);
1489 ofpbuf_use_stack(&buf
, maskbuf
, sizeof *maskbuf
);
1490 odp_flow_key_from_mask(&buf
, &wc
.masks
, &netdev_flow
->flow
,
1491 odp_to_u32(wc
.masks
.in_port
.odp_port
),
1493 f
->mask
= ofpbuf_data(&buf
);
1494 f
->mask_len
= ofpbuf_size(&buf
);
1497 dp_actions
= dp_netdev_flow_get_actions(netdev_flow
);
1498 f
->actions
= dp_actions
->actions
;
1499 f
->actions_len
= dp_actions
->size
;
1502 get_dpif_flow_stats(netdev_flow
, &f
->stats
);
1509 dpif_netdev_execute(struct dpif
*dpif
, struct dpif_execute
*execute
)
1511 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1512 struct dpif_packet packet
, *pp
;
1513 struct pkt_metadata
*md
= &execute
->md
;
1515 if (ofpbuf_size(execute
->packet
) < ETH_HEADER_LEN
||
1516 ofpbuf_size(execute
->packet
) > UINT16_MAX
) {
1520 packet
.ofpbuf
= *execute
->packet
;
1523 dp_netdev_execute_actions(dp
, &pp
, 1, false, md
,
1524 execute
->actions
, execute
->actions_len
);
1526 /* Even though may_steal is set to false, some actions could modify or
1527 * reallocate the ofpbuf memory. We need to pass those changes to the
1529 *execute
->packet
= packet
.ofpbuf
;
1535 dpif_netdev_operate(struct dpif
*dpif
, struct dpif_op
**ops
, size_t n_ops
)
1539 for (i
= 0; i
< n_ops
; i
++) {
1540 struct dpif_op
*op
= ops
[i
];
1543 case DPIF_OP_FLOW_PUT
:
1544 op
->error
= dpif_netdev_flow_put(dpif
, &op
->u
.flow_put
);
1547 case DPIF_OP_FLOW_DEL
:
1548 op
->error
= dpif_netdev_flow_del(dpif
, &op
->u
.flow_del
);
1551 case DPIF_OP_EXECUTE
:
1552 op
->error
= dpif_netdev_execute(dpif
, &op
->u
.execute
);
1555 case DPIF_OP_FLOW_GET
:
1556 op
->error
= dpif_netdev_flow_get(dpif
, &op
->u
.flow_get
);
1563 dpif_netdev_queue_to_priority(const struct dpif
*dpif OVS_UNUSED
,
1564 uint32_t queue_id
, uint32_t *priority
)
1566 *priority
= queue_id
;
1571 /* Creates and returns a new 'struct dp_netdev_actions', with a reference count
1572 * of 1, whose actions are a copy of from the 'ofpacts_len' bytes of
1574 struct dp_netdev_actions
*
1575 dp_netdev_actions_create(const struct nlattr
*actions
, size_t size
)
1577 struct dp_netdev_actions
*netdev_actions
;
1579 netdev_actions
= xmalloc(sizeof *netdev_actions
);
1580 netdev_actions
->actions
= xmemdup(actions
, size
);
1581 netdev_actions
->size
= size
;
1583 return netdev_actions
;
1586 struct dp_netdev_actions
*
1587 dp_netdev_flow_get_actions(const struct dp_netdev_flow
*flow
)
1589 return ovsrcu_get(struct dp_netdev_actions
*, &flow
->actions
);
1593 dp_netdev_actions_free(struct dp_netdev_actions
*actions
)
1595 free(actions
->actions
);
1601 dp_netdev_process_rxq_port(struct dp_netdev
*dp
,
1602 struct dp_netdev_port
*port
,
1603 struct netdev_rxq
*rxq
)
1605 struct dpif_packet
*packets
[NETDEV_MAX_RX_BATCH
];
1608 error
= netdev_rxq_recv(rxq
, packets
, &cnt
);
1610 dp_netdev_port_input(dp
, packets
, cnt
, port
->port_no
);
1611 } else if (error
!= EAGAIN
&& error
!= EOPNOTSUPP
) {
1612 static struct vlog_rate_limit rl
1613 = VLOG_RATE_LIMIT_INIT(1, 5);
1615 VLOG_ERR_RL(&rl
, "error receiving data from %s: %s",
1616 netdev_get_name(port
->netdev
),
1617 ovs_strerror(error
));
1622 dpif_netdev_run(struct dpif
*dpif
)
1624 struct dp_netdev_port
*port
;
1625 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1627 CMAP_FOR_EACH (port
, node
, &dp
->ports
) {
1628 if (!netdev_is_pmd(port
->netdev
)) {
1631 for (i
= 0; i
< netdev_n_rxq(port
->netdev
); i
++) {
1632 dp_netdev_process_rxq_port(dp
, port
, port
->rxq
[i
]);
1639 dpif_netdev_wait(struct dpif
*dpif
)
1641 struct dp_netdev_port
*port
;
1642 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1644 ovs_mutex_lock(&dp_netdev_mutex
);
1645 CMAP_FOR_EACH (port
, node
, &dp
->ports
) {
1646 if (!netdev_is_pmd(port
->netdev
)) {
1649 for (i
= 0; i
< netdev_n_rxq(port
->netdev
); i
++) {
1650 netdev_rxq_wait(port
->rxq
[i
]);
1654 ovs_mutex_unlock(&dp_netdev_mutex
);
1658 struct dp_netdev_port
*port
;
1659 struct netdev_rxq
*rx
;
1663 pmd_load_queues(struct pmd_thread
*f
,
1664 struct rxq_poll
**ppoll_list
, int poll_cnt
)
1666 struct dp_netdev
*dp
= f
->dp
;
1667 struct rxq_poll
*poll_list
= *ppoll_list
;
1668 struct dp_netdev_port
*port
;
1673 /* Simple scheduler for netdev rx polling. */
1674 for (i
= 0; i
< poll_cnt
; i
++) {
1675 port_unref(poll_list
[i
].port
);
1681 CMAP_FOR_EACH (port
, node
, &f
->dp
->ports
) {
1682 if (netdev_is_pmd(port
->netdev
)) {
1685 for (i
= 0; i
< netdev_n_rxq(port
->netdev
); i
++) {
1686 if ((index
% dp
->n_pmd_threads
) == id
) {
1687 poll_list
= xrealloc(poll_list
, sizeof *poll_list
* (poll_cnt
+ 1));
1690 poll_list
[poll_cnt
].port
= port
;
1691 poll_list
[poll_cnt
].rx
= port
->rxq
[i
];
1699 *ppoll_list
= poll_list
;
1704 pmd_thread_main(void *f_
)
1706 struct pmd_thread
*f
= f_
;
1707 struct dp_netdev
*dp
= f
->dp
;
1708 unsigned int lc
= 0;
1709 struct rxq_poll
*poll_list
;
1710 unsigned int port_seq
= PMD_INITIAL_SEQ
;
1717 pmd_thread_setaffinity_cpu(f
->id
);
1719 poll_cnt
= pmd_load_queues(f
, &poll_list
, poll_cnt
);
1724 for (i
= 0; i
< poll_cnt
; i
++) {
1725 dp_netdev_process_rxq_port(dp
, poll_list
[i
].port
, poll_list
[i
].rx
);
1735 atomic_read_relaxed(&f
->change_seq
, &seq
);
1736 if (seq
!= port_seq
) {
1743 if (!latch_is_set(&f
->dp
->exit_latch
)){
1747 for (i
= 0; i
< poll_cnt
; i
++) {
1748 port_unref(poll_list
[i
].port
);
1756 dp_netdev_disable_upcall(struct dp_netdev
*dp
)
1757 OVS_ACQUIRES(dp
->upcall_rwlock
)
1759 fat_rwlock_wrlock(&dp
->upcall_rwlock
);
1763 dpif_netdev_disable_upcall(struct dpif
*dpif
)
1764 OVS_NO_THREAD_SAFETY_ANALYSIS
1766 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1767 dp_netdev_disable_upcall(dp
);
1771 dp_netdev_enable_upcall(struct dp_netdev
*dp
)
1772 OVS_RELEASES(dp
->upcall_rwlock
)
1774 fat_rwlock_unlock(&dp
->upcall_rwlock
);
1778 dpif_netdev_enable_upcall(struct dpif
*dpif
)
1779 OVS_NO_THREAD_SAFETY_ANALYSIS
1781 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1782 dp_netdev_enable_upcall(dp
);
1786 dp_netdev_set_pmd_threads(struct dp_netdev
*dp
, int n
)
1790 if (n
== dp
->n_pmd_threads
) {
1794 /* Stop existing threads. */
1795 latch_set(&dp
->exit_latch
);
1796 dp_netdev_reload_pmd_threads(dp
);
1797 for (i
= 0; i
< dp
->n_pmd_threads
; i
++) {
1798 struct pmd_thread
*f
= &dp
->pmd_threads
[i
];
1800 xpthread_join(f
->thread
, NULL
);
1802 latch_poll(&dp
->exit_latch
);
1803 free(dp
->pmd_threads
);
1805 /* Start new threads. */
1806 dp
->pmd_threads
= xmalloc(n
* sizeof *dp
->pmd_threads
);
1807 dp
->n_pmd_threads
= n
;
1809 for (i
= 0; i
< n
; i
++) {
1810 struct pmd_thread
*f
= &dp
->pmd_threads
[i
];
1814 atomic_init(&f
->change_seq
, PMD_INITIAL_SEQ
);
1816 /* Each thread will distribute all devices rx-queues among
1818 f
->thread
= ovs_thread_create("pmd", pmd_thread_main
, f
);
1824 dp_netdev_flow_stats_new_cb(void)
1826 struct dp_netdev_flow_stats
*bucket
= xzalloc_cacheline(sizeof *bucket
);
1827 ovs_mutex_init(&bucket
->mutex
);
1832 dp_netdev_flow_used(struct dp_netdev_flow
*netdev_flow
,
1836 long long int now
= time_msec();
1837 struct dp_netdev_flow_stats
*bucket
;
1839 bucket
= ovsthread_stats_bucket_get(&netdev_flow
->stats
,
1840 dp_netdev_flow_stats_new_cb
);
1842 ovs_mutex_lock(&bucket
->mutex
);
1843 bucket
->used
= MAX(now
, bucket
->used
);
1844 bucket
->packet_count
+= cnt
;
1845 bucket
->byte_count
+= size
;
1846 bucket
->tcp_flags
|= tcp_flags
;
1847 ovs_mutex_unlock(&bucket
->mutex
);
1851 dp_netdev_stats_new_cb(void)
1853 struct dp_netdev_stats
*bucket
= xzalloc_cacheline(sizeof *bucket
);
1854 ovs_mutex_init(&bucket
->mutex
);
1859 dp_netdev_count_packet(struct dp_netdev
*dp
, enum dp_stat_type type
, int cnt
)
1861 struct dp_netdev_stats
*bucket
;
1863 bucket
= ovsthread_stats_bucket_get(&dp
->stats
, dp_netdev_stats_new_cb
);
1864 ovs_mutex_lock(&bucket
->mutex
);
1865 bucket
->n
[type
] += cnt
;
1866 ovs_mutex_unlock(&bucket
->mutex
);
1870 dp_netdev_upcall(struct dp_netdev
*dp
, struct dpif_packet
*packet_
,
1871 struct flow
*flow
, struct flow_wildcards
*wc
,
1872 enum dpif_upcall_type type
, const struct nlattr
*userdata
,
1873 struct ofpbuf
*actions
, struct ofpbuf
*put_actions
)
1875 struct ofpbuf
*packet
= &packet_
->ofpbuf
;
1877 if (type
== DPIF_UC_MISS
) {
1878 dp_netdev_count_packet(dp
, DP_STAT_MISS
, 1);
1881 if (OVS_UNLIKELY(!dp
->upcall_cb
)) {
1885 if (OVS_UNLIKELY(!VLOG_DROP_DBG(&upcall_rl
))) {
1886 struct ds ds
= DS_EMPTY_INITIALIZER
;
1890 ofpbuf_init(&key
, 0);
1891 odp_flow_key_from_flow(&key
, flow
, &wc
->masks
, flow
->in_port
.odp_port
,
1894 packet_str
= ofp_packet_to_string(ofpbuf_data(packet
),
1895 ofpbuf_size(packet
));
1897 odp_flow_key_format(ofpbuf_data(&key
), ofpbuf_size(&key
), &ds
);
1899 VLOG_DBG("%s: %s upcall:\n%s\n%s", dp
->name
,
1900 dpif_upcall_type_to_string(type
), ds_cstr(&ds
), packet_str
);
1902 ofpbuf_uninit(&key
);
1907 return dp
->upcall_cb(packet
, flow
, type
, userdata
, actions
, wc
,
1908 put_actions
, dp
->upcall_aux
);
1911 struct packet_batch
{
1912 unsigned int packet_count
;
1913 unsigned int byte_count
;
1916 struct dp_netdev_flow
*flow
;
1918 struct dpif_packet
*packets
[NETDEV_MAX_RX_BATCH
];
1919 struct pkt_metadata md
;
1923 packet_batch_update(struct packet_batch
*batch
,
1924 struct dpif_packet
*packet
, const struct miniflow
*mf
)
1926 batch
->tcp_flags
|= miniflow_get_tcp_flags(mf
);
1927 batch
->packets
[batch
->packet_count
++] = packet
;
1928 batch
->byte_count
+= ofpbuf_size(&packet
->ofpbuf
);
1932 packet_batch_init(struct packet_batch
*batch
, struct dp_netdev_flow
*flow
,
1933 struct pkt_metadata
*md
)
1938 batch
->packet_count
= 0;
1939 batch
->byte_count
= 0;
1940 batch
->tcp_flags
= 0;
1944 packet_batch_execute(struct packet_batch
*batch
, struct dp_netdev
*dp
)
1946 struct dp_netdev_actions
*actions
;
1947 struct dp_netdev_flow
*flow
= batch
->flow
;
1949 dp_netdev_flow_used(batch
->flow
, batch
->packet_count
, batch
->byte_count
,
1952 actions
= dp_netdev_flow_get_actions(flow
);
1954 dp_netdev_execute_actions(dp
, batch
->packets
,
1955 batch
->packet_count
, true, &batch
->md
,
1956 actions
->actions
, actions
->size
);
1958 dp_netdev_count_packet(dp
, DP_STAT_HIT
, batch
->packet_count
);
1962 dp_netdev_input(struct dp_netdev
*dp
, struct dpif_packet
**packets
, int cnt
,
1963 struct pkt_metadata
*md
)
1965 struct packet_batch batches
[NETDEV_MAX_RX_BATCH
];
1966 struct netdev_flow_key keys
[NETDEV_MAX_RX_BATCH
];
1967 const struct miniflow
*mfs
[NETDEV_MAX_RX_BATCH
]; /* NULL at bad packets. */
1968 struct cls_rule
*rules
[NETDEV_MAX_RX_BATCH
];
1969 size_t n_batches
, i
;
1972 for (i
= 0; i
< cnt
; i
++) {
1973 if (OVS_UNLIKELY(ofpbuf_size(&packets
[i
]->ofpbuf
) < ETH_HEADER_LEN
)) {
1974 dpif_packet_delete(packets
[i
]);
1979 miniflow_initialize(&keys
[i
].flow
, keys
[i
].buf
);
1980 miniflow_extract(&packets
[i
]->ofpbuf
, md
, &keys
[i
].flow
);
1981 mfs
[i
] = &keys
[i
].flow
;
1984 any_miss
= !classifier_lookup_miniflow_batch(&dp
->cls
, mfs
, rules
, cnt
);
1985 if (OVS_UNLIKELY(any_miss
) && !fat_rwlock_tryrdlock(&dp
->upcall_rwlock
)) {
1986 uint64_t actions_stub
[512 / 8], slow_stub
[512 / 8];
1987 struct ofpbuf actions
, put_actions
;
1990 ofpbuf_use_stub(&actions
, actions_stub
, sizeof actions_stub
);
1991 ofpbuf_use_stub(&put_actions
, slow_stub
, sizeof slow_stub
);
1993 for (i
= 0; i
< cnt
; i
++) {
1994 const struct dp_netdev_flow
*netdev_flow
;
1995 struct ofpbuf
*add_actions
;
1998 if (OVS_LIKELY(rules
[i
] || !mfs
[i
])) {
2002 /* It's possible that an earlier slow path execution installed
2003 * the rule this flow needs. In this case, it's a lot cheaper
2004 * to catch it here than execute a miss. */
2005 netdev_flow
= dp_netdev_lookup_flow(dp
, mfs
[i
]);
2007 rules
[i
] = CONST_CAST(struct cls_rule
*, &netdev_flow
->cr
);
2011 miniflow_expand(mfs
[i
], &match
.flow
);
2013 ofpbuf_clear(&actions
);
2014 ofpbuf_clear(&put_actions
);
2016 error
= dp_netdev_upcall(dp
, packets
[i
], &match
.flow
, &match
.wc
,
2017 DPIF_UC_MISS
, NULL
, &actions
,
2019 if (OVS_UNLIKELY(error
&& error
!= ENOSPC
)) {
2023 /* We can't allow the packet batching in the next loop to execute
2024 * the actions. Otherwise, if there are any slow path actions,
2025 * we'll send the packet up twice. */
2026 dp_netdev_execute_actions(dp
, &packets
[i
], 1, false, md
,
2027 ofpbuf_data(&actions
),
2028 ofpbuf_size(&actions
));
2030 add_actions
= ofpbuf_size(&put_actions
)
2034 ovs_mutex_lock(&dp
->flow_mutex
);
2035 /* XXX: There's a brief race where this flow could have already
2036 * been installed since we last did the flow lookup. This could be
2037 * solved by moving the mutex lock outside the loop, but that's an
2038 * awful long time to be locking everyone out of making flow
2039 * installs. If we move to a per-core classifier, it would be
2041 if (OVS_LIKELY(error
!= ENOSPC
)
2042 && !dp_netdev_lookup_flow(dp
, mfs
[i
])) {
2043 dp_netdev_flow_add(dp
, &match
, ofpbuf_data(add_actions
),
2044 ofpbuf_size(add_actions
));
2046 ovs_mutex_unlock(&dp
->flow_mutex
);
2049 ofpbuf_uninit(&actions
);
2050 ofpbuf_uninit(&put_actions
);
2051 fat_rwlock_unlock(&dp
->upcall_rwlock
);
2055 for (i
= 0; i
< cnt
; i
++) {
2056 struct dp_netdev_flow
*flow
;
2057 struct packet_batch
*batch
;
2060 if (OVS_UNLIKELY(!rules
[i
] || !mfs
[i
])) {
2064 /* XXX: This O(n^2) algortihm makes sense if we're operating under the
2065 * assumption that the number of distinct flows (and therefore the
2066 * number of distinct batches) is quite small. If this turns out not
2067 * to be the case, it may make sense to pre sort based on the
2068 * netdev_flow pointer. That done we can get the appropriate batching
2069 * in O(n * log(n)) instead. */
2071 flow
= dp_netdev_flow_cast(rules
[i
]);
2072 for (j
= 0; j
< n_batches
; j
++) {
2073 if (batches
[j
].flow
== flow
) {
2074 batch
= &batches
[j
];
2080 batch
= &batches
[n_batches
++];
2081 packet_batch_init(batch
, flow
, md
);
2083 packet_batch_update(batch
, packets
[i
], mfs
[i
]);
2086 for (i
= 0; i
< n_batches
; i
++) {
2087 packet_batch_execute(&batches
[i
], dp
);
2092 dp_netdev_port_input(struct dp_netdev
*dp
, struct dpif_packet
**packets
,
2093 int cnt
, odp_port_t port_no
)
2095 uint32_t *recirc_depth
= recirc_depth_get();
2096 struct pkt_metadata md
= PKT_METADATA_INITIALIZER(port_no
);
2099 dp_netdev_input(dp
, packets
, cnt
, &md
);
2102 struct dp_netdev_execute_aux
{
2103 struct dp_netdev
*dp
;
2107 dpif_netdev_register_upcall_cb(struct dpif
*dpif
, upcall_callback
*cb
,
2110 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
2111 dp
->upcall_aux
= aux
;
2116 dp_execute_cb(void *aux_
, struct dpif_packet
**packets
, int cnt
,
2117 struct pkt_metadata
*md
,
2118 const struct nlattr
*a
, bool may_steal
)
2119 OVS_NO_THREAD_SAFETY_ANALYSIS
2121 struct dp_netdev_execute_aux
*aux
= aux_
;
2122 uint32_t *depth
= recirc_depth_get();
2123 struct dp_netdev
*dp
= aux
->dp
;
2124 int type
= nl_attr_type(a
);
2125 struct dp_netdev_port
*p
;
2128 switch ((enum ovs_action_attr
)type
) {
2129 case OVS_ACTION_ATTR_OUTPUT
:
2130 p
= dp_netdev_lookup_port(dp
, u32_to_odp(nl_attr_get_u32(a
)));
2131 if (OVS_LIKELY(p
)) {
2132 netdev_send(p
->netdev
, packets
, cnt
, may_steal
);
2133 } else if (may_steal
) {
2134 for (i
= 0; i
< cnt
; i
++) {
2135 dpif_packet_delete(packets
[i
]);
2140 case OVS_ACTION_ATTR_USERSPACE
:
2141 if (!fat_rwlock_tryrdlock(&dp
->upcall_rwlock
)) {
2142 const struct nlattr
*userdata
;
2143 struct ofpbuf actions
;
2146 userdata
= nl_attr_find_nested(a
, OVS_USERSPACE_ATTR_USERDATA
);
2147 ofpbuf_init(&actions
, 0);
2149 for (i
= 0; i
< cnt
; i
++) {
2152 ofpbuf_clear(&actions
);
2154 flow_extract(&packets
[i
]->ofpbuf
, md
, &flow
);
2155 error
= dp_netdev_upcall(dp
, packets
[i
], &flow
, NULL
,
2156 DPIF_UC_ACTION
, userdata
, &actions
,
2158 if (!error
|| error
== ENOSPC
) {
2159 dp_netdev_execute_actions(dp
, &packets
[i
], 1, false, md
,
2160 ofpbuf_data(&actions
),
2161 ofpbuf_size(&actions
));
2165 dpif_packet_delete(packets
[i
]);
2168 ofpbuf_uninit(&actions
);
2169 fat_rwlock_unlock(&dp
->upcall_rwlock
);
2174 case OVS_ACTION_ATTR_HASH
: {
2175 const struct ovs_action_hash
*hash_act
;
2176 struct netdev_flow_key key
;
2179 hash_act
= nl_attr_get(a
);
2181 miniflow_initialize(&key
.flow
, key
.buf
);
2183 for (i
= 0; i
< cnt
; i
++) {
2185 /* XXX: this is slow. Use RSS hash in the future */
2186 miniflow_extract(&packets
[i
]->ofpbuf
, md
, &key
.flow
);
2188 if (hash_act
->hash_alg
== OVS_HASH_ALG_L4
) {
2189 /* Hash need not be symmetric, nor does it need to include
2191 hash
= miniflow_hash_5tuple(&key
.flow
, hash_act
->hash_basis
);
2193 VLOG_WARN("Unknown hash algorithm specified "
2194 "for the hash action.");
2199 hash
= 1; /* 0 is not valid */
2205 packets
[i
]->dp_hash
= hash
;
2210 case OVS_ACTION_ATTR_RECIRC
:
2211 if (*depth
< MAX_RECIRC_DEPTH
) {
2214 for (i
= 0; i
< cnt
; i
++) {
2215 struct dpif_packet
*recirc_pkt
;
2216 struct pkt_metadata recirc_md
= *md
;
2218 recirc_pkt
= (may_steal
) ? packets
[i
]
2219 : dpif_packet_clone(packets
[i
]);
2221 recirc_md
.recirc_id
= nl_attr_get_u32(a
);
2223 /* Hash is private to each packet */
2224 recirc_md
.dp_hash
= dpif_packet_get_dp_hash(packets
[i
]);
2226 dp_netdev_input(dp
, &recirc_pkt
, 1, &recirc_md
);
2232 VLOG_WARN("Packet dropped. Max recirculation depth exceeded.");
2234 for (i
= 0; i
< cnt
; i
++) {
2235 dpif_packet_delete(packets
[i
]);
2241 case OVS_ACTION_ATTR_PUSH_VLAN
:
2242 case OVS_ACTION_ATTR_POP_VLAN
:
2243 case OVS_ACTION_ATTR_PUSH_MPLS
:
2244 case OVS_ACTION_ATTR_POP_MPLS
:
2245 case OVS_ACTION_ATTR_SET
:
2246 case OVS_ACTION_ATTR_SAMPLE
:
2247 case OVS_ACTION_ATTR_UNSPEC
:
2248 case __OVS_ACTION_ATTR_MAX
:
2254 dp_netdev_execute_actions(struct dp_netdev
*dp
,
2255 struct dpif_packet
**packets
, int cnt
,
2256 bool may_steal
, struct pkt_metadata
*md
,
2257 const struct nlattr
*actions
, size_t actions_len
)
2259 struct dp_netdev_execute_aux aux
= {dp
};
2261 odp_execute_actions(&aux
, packets
, cnt
, may_steal
, md
, actions
,
2262 actions_len
, dp_execute_cb
);
2265 const struct dpif_class dpif_netdev_class
= {
2267 dpif_netdev_enumerate
,
2268 dpif_netdev_port_open_type
,
2271 dpif_netdev_destroy
,
2274 dpif_netdev_get_stats
,
2275 dpif_netdev_port_add
,
2276 dpif_netdev_port_del
,
2277 dpif_netdev_port_query_by_number
,
2278 dpif_netdev_port_query_by_name
,
2279 NULL
, /* port_get_pid */
2280 dpif_netdev_port_dump_start
,
2281 dpif_netdev_port_dump_next
,
2282 dpif_netdev_port_dump_done
,
2283 dpif_netdev_port_poll
,
2284 dpif_netdev_port_poll_wait
,
2285 dpif_netdev_flow_flush
,
2286 dpif_netdev_flow_dump_create
,
2287 dpif_netdev_flow_dump_destroy
,
2288 dpif_netdev_flow_dump_thread_create
,
2289 dpif_netdev_flow_dump_thread_destroy
,
2290 dpif_netdev_flow_dump_next
,
2291 dpif_netdev_operate
,
2292 NULL
, /* recv_set */
2293 NULL
, /* handlers_set */
2294 dpif_netdev_queue_to_priority
,
2296 NULL
, /* recv_wait */
2297 NULL
, /* recv_purge */
2298 dpif_netdev_register_upcall_cb
,
2299 dpif_netdev_enable_upcall
,
2300 dpif_netdev_disable_upcall
,
2304 dpif_dummy_change_port_number(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
2305 const char *argv
[], void *aux OVS_UNUSED
)
2307 struct dp_netdev_port
*old_port
;
2308 struct dp_netdev_port
*new_port
;
2309 struct dp_netdev
*dp
;
2312 ovs_mutex_lock(&dp_netdev_mutex
);
2313 dp
= shash_find_data(&dp_netdevs
, argv
[1]);
2314 if (!dp
|| !dpif_netdev_class_is_dummy(dp
->class)) {
2315 ovs_mutex_unlock(&dp_netdev_mutex
);
2316 unixctl_command_reply_error(conn
, "unknown datapath or not a dummy");
2319 ovs_refcount_ref(&dp
->ref_cnt
);
2320 ovs_mutex_unlock(&dp_netdev_mutex
);
2322 ovs_mutex_lock(&dp
->port_mutex
);
2323 if (get_port_by_name(dp
, argv
[2], &old_port
)) {
2324 unixctl_command_reply_error(conn
, "unknown port");
2328 port_no
= u32_to_odp(atoi(argv
[3]));
2329 if (!port_no
|| port_no
== ODPP_NONE
) {
2330 unixctl_command_reply_error(conn
, "bad port number");
2333 if (dp_netdev_lookup_port(dp
, port_no
)) {
2334 unixctl_command_reply_error(conn
, "port number already in use");
2338 /* Remove old port. */
2339 cmap_remove(&dp
->ports
, &old_port
->node
, hash_port_no(old_port
->port_no
));
2340 ovsrcu_postpone(free
, old_port
);
2342 /* Insert new port (cmap semantics mean we cannot re-insert 'old_port'). */
2343 new_port
= xmemdup(old_port
, sizeof *old_port
);
2344 new_port
->port_no
= port_no
;
2345 cmap_insert(&dp
->ports
, &new_port
->node
, hash_port_no(port_no
));
2347 seq_change(dp
->port_seq
);
2348 unixctl_command_reply(conn
, NULL
);
2351 ovs_mutex_unlock(&dp
->port_mutex
);
2352 dp_netdev_unref(dp
);
2356 dpif_dummy_delete_port(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
2357 const char *argv
[], void *aux OVS_UNUSED
)
2359 struct dp_netdev_port
*port
;
2360 struct dp_netdev
*dp
;
2362 ovs_mutex_lock(&dp_netdev_mutex
);
2363 dp
= shash_find_data(&dp_netdevs
, argv
[1]);
2364 if (!dp
|| !dpif_netdev_class_is_dummy(dp
->class)) {
2365 ovs_mutex_unlock(&dp_netdev_mutex
);
2366 unixctl_command_reply_error(conn
, "unknown datapath or not a dummy");
2369 ovs_refcount_ref(&dp
->ref_cnt
);
2370 ovs_mutex_unlock(&dp_netdev_mutex
);
2372 ovs_mutex_lock(&dp
->port_mutex
);
2373 if (get_port_by_name(dp
, argv
[2], &port
)) {
2374 unixctl_command_reply_error(conn
, "unknown port");
2375 } else if (port
->port_no
== ODPP_LOCAL
) {
2376 unixctl_command_reply_error(conn
, "can't delete local port");
2378 do_del_port(dp
, port
);
2379 unixctl_command_reply(conn
, NULL
);
2381 ovs_mutex_unlock(&dp
->port_mutex
);
2383 dp_netdev_unref(dp
);
2387 dpif_dummy_register__(const char *type
)
2389 struct dpif_class
*class;
2391 class = xmalloc(sizeof *class);
2392 *class = dpif_netdev_class
;
2393 class->type
= xstrdup(type
);
2394 dp_register_provider(class);
2398 dpif_dummy_register(bool override
)
2405 dp_enumerate_types(&types
);
2406 SSET_FOR_EACH (type
, &types
) {
2407 if (!dp_unregister_provider(type
)) {
2408 dpif_dummy_register__(type
);
2411 sset_destroy(&types
);
2414 dpif_dummy_register__("dummy");
2416 unixctl_command_register("dpif-dummy/change-port-number",
2417 "DP PORT NEW-NUMBER",
2418 3, 3, dpif_dummy_change_port_number
, NULL
);
2419 unixctl_command_register("dpif-dummy/delete-port", "DP PORT",
2420 2, 2, dpif_dummy_delete_port
, NULL
);