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 /* Interface to netdev-based datapath. */
303 struct dp_netdev
*dp
;
304 uint64_t last_port_seq
;
307 static int get_port_by_number(struct dp_netdev
*dp
, odp_port_t port_no
,
308 struct dp_netdev_port
**portp
);
309 static int get_port_by_name(struct dp_netdev
*dp
, const char *devname
,
310 struct dp_netdev_port
**portp
);
311 static void dp_netdev_free(struct dp_netdev
*)
312 OVS_REQUIRES(dp_netdev_mutex
);
313 static void dp_netdev_flow_flush(struct dp_netdev
*);
314 static int do_add_port(struct dp_netdev
*dp
, const char *devname
,
315 const char *type
, odp_port_t port_no
)
316 OVS_REQUIRES(dp
->port_mutex
);
317 static void do_del_port(struct dp_netdev
*dp
, struct dp_netdev_port
*)
318 OVS_REQUIRES(dp
->port_mutex
);
319 static int dpif_netdev_open(const struct dpif_class
*, const char *name
,
320 bool create
, struct dpif
**);
321 static void dp_netdev_execute_actions(struct dp_netdev
*dp
,
322 struct dpif_packet
**, int c
,
323 bool may_steal
, struct pkt_metadata
*,
324 const struct nlattr
*actions
,
326 static void dp_netdev_port_input(struct dp_netdev
*dp
,
327 struct dpif_packet
**packets
, int cnt
,
330 static void dp_netdev_set_pmd_threads(struct dp_netdev
*, int n
);
331 static void dp_netdev_disable_upcall(struct dp_netdev
*);
333 static struct dpif_netdev
*
334 dpif_netdev_cast(const struct dpif
*dpif
)
336 ovs_assert(dpif
->dpif_class
->open
== dpif_netdev_open
);
337 return CONTAINER_OF(dpif
, struct dpif_netdev
, dpif
);
340 static struct dp_netdev
*
341 get_dp_netdev(const struct dpif
*dpif
)
343 return dpif_netdev_cast(dpif
)->dp
;
347 dpif_netdev_enumerate(struct sset
*all_dps
,
348 const struct dpif_class
*dpif_class
)
350 struct shash_node
*node
;
352 ovs_mutex_lock(&dp_netdev_mutex
);
353 SHASH_FOR_EACH(node
, &dp_netdevs
) {
354 struct dp_netdev
*dp
= node
->data
;
355 if (dpif_class
!= dp
->class) {
356 /* 'dp_netdevs' contains both "netdev" and "dummy" dpifs.
357 * If the class doesn't match, skip this dpif. */
360 sset_add(all_dps
, node
->name
);
362 ovs_mutex_unlock(&dp_netdev_mutex
);
368 dpif_netdev_class_is_dummy(const struct dpif_class
*class)
370 return class != &dpif_netdev_class
;
374 dpif_netdev_port_open_type(const struct dpif_class
*class, const char *type
)
376 return strcmp(type
, "internal") ? type
377 : dpif_netdev_class_is_dummy(class) ? "dummy"
382 create_dpif_netdev(struct dp_netdev
*dp
)
384 uint16_t netflow_id
= hash_string(dp
->name
, 0);
385 struct dpif_netdev
*dpif
;
387 ovs_refcount_ref(&dp
->ref_cnt
);
389 dpif
= xmalloc(sizeof *dpif
);
390 dpif_init(&dpif
->dpif
, dp
->class, dp
->name
, netflow_id
>> 8, netflow_id
);
392 dpif
->last_port_seq
= seq_read(dp
->port_seq
);
397 /* Choose an unused, non-zero port number and return it on success.
398 * Return ODPP_NONE on failure. */
400 choose_port(struct dp_netdev
*dp
, const char *name
)
401 OVS_REQUIRES(dp
->port_mutex
)
405 if (dp
->class != &dpif_netdev_class
) {
409 /* If the port name begins with "br", start the number search at
410 * 100 to make writing tests easier. */
411 if (!strncmp(name
, "br", 2)) {
415 /* If the port name contains a number, try to assign that port number.
416 * This can make writing unit tests easier because port numbers are
418 for (p
= name
; *p
!= '\0'; p
++) {
419 if (isdigit((unsigned char) *p
)) {
420 port_no
= start_no
+ strtol(p
, NULL
, 10);
421 if (port_no
> 0 && port_no
!= odp_to_u32(ODPP_NONE
)
422 && !dp_netdev_lookup_port(dp
, u32_to_odp(port_no
))) {
423 return u32_to_odp(port_no
);
430 for (port_no
= 1; port_no
<= UINT16_MAX
; port_no
++) {
431 if (!dp_netdev_lookup_port(dp
, u32_to_odp(port_no
))) {
432 return u32_to_odp(port_no
);
440 create_dp_netdev(const char *name
, const struct dpif_class
*class,
441 struct dp_netdev
**dpp
)
442 OVS_REQUIRES(dp_netdev_mutex
)
444 struct dp_netdev
*dp
;
447 dp
= xzalloc(sizeof *dp
);
448 shash_add(&dp_netdevs
, name
, dp
);
450 *CONST_CAST(const struct dpif_class
**, &dp
->class) = class;
451 *CONST_CAST(const char **, &dp
->name
) = xstrdup(name
);
452 ovs_refcount_init(&dp
->ref_cnt
);
453 atomic_flag_clear(&dp
->destroyed
);
455 ovs_mutex_init(&dp
->flow_mutex
);
456 classifier_init(&dp
->cls
, NULL
);
457 cmap_init(&dp
->flow_table
);
459 ovsthread_stats_init(&dp
->stats
);
461 ovs_mutex_init(&dp
->port_mutex
);
462 cmap_init(&dp
->ports
);
463 dp
->port_seq
= seq_create();
464 latch_init(&dp
->exit_latch
);
465 fat_rwlock_init(&dp
->upcall_rwlock
);
467 /* Disable upcalls by default. */
468 dp_netdev_disable_upcall(dp
);
469 dp
->upcall_aux
= NULL
;
470 dp
->upcall_cb
= NULL
;
472 ovs_mutex_lock(&dp
->port_mutex
);
473 error
= do_add_port(dp
, name
, "internal", ODPP_LOCAL
);
474 ovs_mutex_unlock(&dp
->port_mutex
);
485 dpif_netdev_open(const struct dpif_class
*class, const char *name
,
486 bool create
, struct dpif
**dpifp
)
488 struct dp_netdev
*dp
;
491 ovs_mutex_lock(&dp_netdev_mutex
);
492 dp
= shash_find_data(&dp_netdevs
, name
);
494 error
= create
? create_dp_netdev(name
, class, &dp
) : ENODEV
;
496 error
= (dp
->class != class ? EINVAL
501 *dpifp
= create_dpif_netdev(dp
);
504 ovs_mutex_unlock(&dp_netdev_mutex
);
509 /* Requires dp_netdev_mutex so that we can't get a new reference to 'dp'
510 * through the 'dp_netdevs' shash while freeing 'dp'. */
512 dp_netdev_free(struct dp_netdev
*dp
)
513 OVS_REQUIRES(dp_netdev_mutex
)
515 struct dp_netdev_port
*port
;
516 struct dp_netdev_stats
*bucket
;
519 shash_find_and_delete(&dp_netdevs
, dp
->name
);
521 dp_netdev_set_pmd_threads(dp
, 0);
522 free(dp
->pmd_threads
);
524 dp_netdev_flow_flush(dp
);
525 ovs_mutex_lock(&dp
->port_mutex
);
526 CMAP_FOR_EACH (port
, node
, &dp
->ports
) {
527 do_del_port(dp
, port
);
529 ovs_mutex_unlock(&dp
->port_mutex
);
531 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &dp
->stats
) {
532 ovs_mutex_destroy(&bucket
->mutex
);
533 free_cacheline(bucket
);
535 ovsthread_stats_destroy(&dp
->stats
);
537 classifier_destroy(&dp
->cls
);
538 cmap_destroy(&dp
->flow_table
);
539 ovs_mutex_destroy(&dp
->flow_mutex
);
540 seq_destroy(dp
->port_seq
);
541 cmap_destroy(&dp
->ports
);
542 fat_rwlock_destroy(&dp
->upcall_rwlock
);
543 latch_destroy(&dp
->exit_latch
);
544 free(CONST_CAST(char *, dp
->name
));
549 dp_netdev_unref(struct dp_netdev
*dp
)
552 /* Take dp_netdev_mutex so that, if dp->ref_cnt falls to zero, we can't
553 * get a new reference to 'dp' through the 'dp_netdevs' shash. */
554 ovs_mutex_lock(&dp_netdev_mutex
);
555 if (ovs_refcount_unref_relaxed(&dp
->ref_cnt
) == 1) {
558 ovs_mutex_unlock(&dp_netdev_mutex
);
563 dpif_netdev_close(struct dpif
*dpif
)
565 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
572 dpif_netdev_destroy(struct dpif
*dpif
)
574 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
576 if (!atomic_flag_test_and_set(&dp
->destroyed
)) {
577 if (ovs_refcount_unref_relaxed(&dp
->ref_cnt
) == 1) {
578 /* Can't happen: 'dpif' still owns a reference to 'dp'. */
587 dpif_netdev_get_stats(const struct dpif
*dpif
, struct dpif_dp_stats
*stats
)
589 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
590 struct dp_netdev_stats
*bucket
;
593 stats
->n_flows
= cmap_count(&dp
->flow_table
);
595 stats
->n_hit
= stats
->n_missed
= stats
->n_lost
= 0;
596 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &dp
->stats
) {
597 ovs_mutex_lock(&bucket
->mutex
);
598 stats
->n_hit
+= bucket
->n
[DP_STAT_HIT
];
599 stats
->n_missed
+= bucket
->n
[DP_STAT_MISS
];
600 stats
->n_lost
+= bucket
->n
[DP_STAT_LOST
];
601 ovs_mutex_unlock(&bucket
->mutex
);
603 stats
->n_masks
= UINT32_MAX
;
604 stats
->n_mask_hit
= UINT64_MAX
;
610 dp_netdev_reload_pmd_threads(struct dp_netdev
*dp
)
614 for (i
= 0; i
< dp
->n_pmd_threads
; i
++) {
615 struct pmd_thread
*f
= &dp
->pmd_threads
[i
];
618 atomic_add(&f
->change_seq
, 1, &id
);
623 hash_port_no(odp_port_t port_no
)
625 return hash_int(odp_to_u32(port_no
), 0);
629 do_add_port(struct dp_netdev
*dp
, const char *devname
, const char *type
,
631 OVS_REQUIRES(dp
->port_mutex
)
633 struct netdev_saved_flags
*sf
;
634 struct dp_netdev_port
*port
;
635 struct netdev
*netdev
;
636 enum netdev_flags flags
;
637 const char *open_type
;
641 /* XXX reject devices already in some dp_netdev. */
643 /* Open and validate network device. */
644 open_type
= dpif_netdev_port_open_type(dp
->class, type
);
645 error
= netdev_open(devname
, open_type
, &netdev
);
649 /* XXX reject non-Ethernet devices */
651 netdev_get_flags(netdev
, &flags
);
652 if (flags
& NETDEV_LOOPBACK
) {
653 VLOG_ERR("%s: cannot add a loopback device", devname
);
654 netdev_close(netdev
);
658 port
= xzalloc(sizeof *port
);
659 port
->port_no
= port_no
;
660 port
->netdev
= netdev
;
661 port
->rxq
= xmalloc(sizeof *port
->rxq
* netdev_n_rxq(netdev
));
662 port
->type
= xstrdup(type
);
663 for (i
= 0; i
< netdev_n_rxq(netdev
); i
++) {
664 error
= netdev_rxq_open(netdev
, &port
->rxq
[i
], i
);
666 && !(error
== EOPNOTSUPP
&& dpif_netdev_class_is_dummy(dp
->class))) {
667 VLOG_ERR("%s: cannot receive packets on this network device (%s)",
668 devname
, ovs_strerror(errno
));
669 netdev_close(netdev
);
674 error
= netdev_turn_flags_on(netdev
, NETDEV_PROMISC
, &sf
);
676 for (i
= 0; i
< netdev_n_rxq(netdev
); i
++) {
677 netdev_rxq_close(port
->rxq
[i
]);
679 netdev_close(netdev
);
686 if (netdev_is_pmd(netdev
)) {
688 dp_netdev_set_pmd_threads(dp
, NR_PMD_THREADS
);
689 dp_netdev_reload_pmd_threads(dp
);
691 ovs_refcount_init(&port
->ref_cnt
);
693 cmap_insert(&dp
->ports
, &port
->node
, hash_port_no(port_no
));
694 seq_change(dp
->port_seq
);
700 dpif_netdev_port_add(struct dpif
*dpif
, struct netdev
*netdev
,
701 odp_port_t
*port_nop
)
703 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
704 char namebuf
[NETDEV_VPORT_NAME_BUFSIZE
];
705 const char *dpif_port
;
709 ovs_mutex_lock(&dp
->port_mutex
);
710 dpif_port
= netdev_vport_get_dpif_port(netdev
, namebuf
, sizeof namebuf
);
711 if (*port_nop
!= ODPP_NONE
) {
713 error
= dp_netdev_lookup_port(dp
, *port_nop
) ? EBUSY
: 0;
715 port_no
= choose_port(dp
, dpif_port
);
716 error
= port_no
== ODPP_NONE
? EFBIG
: 0;
720 error
= do_add_port(dp
, dpif_port
, netdev_get_type(netdev
), port_no
);
722 ovs_mutex_unlock(&dp
->port_mutex
);
728 dpif_netdev_port_del(struct dpif
*dpif
, odp_port_t port_no
)
730 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
733 ovs_mutex_lock(&dp
->port_mutex
);
734 if (port_no
== ODPP_LOCAL
) {
737 struct dp_netdev_port
*port
;
739 error
= get_port_by_number(dp
, port_no
, &port
);
741 do_del_port(dp
, port
);
744 ovs_mutex_unlock(&dp
->port_mutex
);
750 is_valid_port_number(odp_port_t port_no
)
752 return port_no
!= ODPP_NONE
;
755 static struct dp_netdev_port
*
756 dp_netdev_lookup_port(const struct dp_netdev
*dp
, odp_port_t port_no
)
758 struct dp_netdev_port
*port
;
760 CMAP_FOR_EACH_WITH_HASH (port
, node
, hash_port_no(port_no
), &dp
->ports
) {
761 if (port
->port_no
== port_no
) {
769 get_port_by_number(struct dp_netdev
*dp
,
770 odp_port_t port_no
, struct dp_netdev_port
**portp
)
772 if (!is_valid_port_number(port_no
)) {
776 *portp
= dp_netdev_lookup_port(dp
, port_no
);
777 return *portp
? 0 : ENOENT
;
782 port_ref(struct dp_netdev_port
*port
)
785 ovs_refcount_ref(&port
->ref_cnt
);
790 port_destroy__(struct dp_netdev_port
*port
)
792 int n_rxq
= netdev_n_rxq(port
->netdev
);
795 netdev_close(port
->netdev
);
796 netdev_restore_flags(port
->sf
);
798 for (i
= 0; i
< n_rxq
; i
++) {
799 netdev_rxq_close(port
->rxq
[i
]);
807 port_unref(struct dp_netdev_port
*port
)
809 if (port
&& ovs_refcount_unref_relaxed(&port
->ref_cnt
) == 1) {
810 ovsrcu_postpone(port_destroy__
, port
);
815 get_port_by_name(struct dp_netdev
*dp
,
816 const char *devname
, struct dp_netdev_port
**portp
)
817 OVS_REQUIRES(dp
->port_mutex
)
819 struct dp_netdev_port
*port
;
821 CMAP_FOR_EACH (port
, node
, &dp
->ports
) {
822 if (!strcmp(netdev_get_name(port
->netdev
), devname
)) {
831 do_del_port(struct dp_netdev
*dp
, struct dp_netdev_port
*port
)
832 OVS_REQUIRES(dp
->port_mutex
)
834 cmap_remove(&dp
->ports
, &port
->node
, hash_odp_port(port
->port_no
));
835 seq_change(dp
->port_seq
);
836 if (netdev_is_pmd(port
->netdev
)) {
837 dp_netdev_reload_pmd_threads(dp
);
844 answer_port_query(const struct dp_netdev_port
*port
,
845 struct dpif_port
*dpif_port
)
847 dpif_port
->name
= xstrdup(netdev_get_name(port
->netdev
));
848 dpif_port
->type
= xstrdup(port
->type
);
849 dpif_port
->port_no
= port
->port_no
;
853 dpif_netdev_port_query_by_number(const struct dpif
*dpif
, odp_port_t port_no
,
854 struct dpif_port
*dpif_port
)
856 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
857 struct dp_netdev_port
*port
;
860 error
= get_port_by_number(dp
, port_no
, &port
);
861 if (!error
&& dpif_port
) {
862 answer_port_query(port
, dpif_port
);
869 dpif_netdev_port_query_by_name(const struct dpif
*dpif
, const char *devname
,
870 struct dpif_port
*dpif_port
)
872 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
873 struct dp_netdev_port
*port
;
876 ovs_mutex_lock(&dp
->port_mutex
);
877 error
= get_port_by_name(dp
, devname
, &port
);
878 if (!error
&& dpif_port
) {
879 answer_port_query(port
, dpif_port
);
881 ovs_mutex_unlock(&dp
->port_mutex
);
887 dp_netdev_flow_free(struct dp_netdev_flow
*flow
)
889 struct dp_netdev_flow_stats
*bucket
;
892 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &flow
->stats
) {
893 ovs_mutex_destroy(&bucket
->mutex
);
894 free_cacheline(bucket
);
896 ovsthread_stats_destroy(&flow
->stats
);
898 cls_rule_destroy(CONST_CAST(struct cls_rule
*, &flow
->cr
));
899 dp_netdev_actions_free(dp_netdev_flow_get_actions(flow
));
903 static void dp_netdev_flow_unref(struct dp_netdev_flow
*flow
)
905 if (ovs_refcount_unref_relaxed(&flow
->ref_cnt
) == 1) {
906 ovsrcu_postpone(dp_netdev_flow_free
, flow
);
911 dp_netdev_remove_flow(struct dp_netdev
*dp
, struct dp_netdev_flow
*flow
)
912 OVS_REQUIRES(dp
->flow_mutex
)
914 struct cls_rule
*cr
= CONST_CAST(struct cls_rule
*, &flow
->cr
);
915 struct cmap_node
*node
= CONST_CAST(struct cmap_node
*, &flow
->node
);
917 classifier_remove(&dp
->cls
, cr
);
918 cmap_remove(&dp
->flow_table
, node
, flow_hash(&flow
->flow
, 0));
920 dp_netdev_flow_unref(flow
);
924 dp_netdev_flow_flush(struct dp_netdev
*dp
)
926 struct dp_netdev_flow
*netdev_flow
;
928 ovs_mutex_lock(&dp
->flow_mutex
);
929 CMAP_FOR_EACH (netdev_flow
, node
, &dp
->flow_table
) {
930 dp_netdev_remove_flow(dp
, netdev_flow
);
932 ovs_mutex_unlock(&dp
->flow_mutex
);
936 dpif_netdev_flow_flush(struct dpif
*dpif
)
938 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
940 dp_netdev_flow_flush(dp
);
944 struct dp_netdev_port_state
{
945 struct cmap_position position
;
950 dpif_netdev_port_dump_start(const struct dpif
*dpif OVS_UNUSED
, void **statep
)
952 *statep
= xzalloc(sizeof(struct dp_netdev_port_state
));
957 dpif_netdev_port_dump_next(const struct dpif
*dpif
, void *state_
,
958 struct dpif_port
*dpif_port
)
960 struct dp_netdev_port_state
*state
= state_
;
961 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
962 struct cmap_node
*node
;
965 node
= cmap_next_position(&dp
->ports
, &state
->position
);
967 struct dp_netdev_port
*port
;
969 port
= CONTAINER_OF(node
, struct dp_netdev_port
, node
);
972 state
->name
= xstrdup(netdev_get_name(port
->netdev
));
973 dpif_port
->name
= state
->name
;
974 dpif_port
->type
= port
->type
;
975 dpif_port
->port_no
= port
->port_no
;
986 dpif_netdev_port_dump_done(const struct dpif
*dpif OVS_UNUSED
, void *state_
)
988 struct dp_netdev_port_state
*state
= state_
;
995 dpif_netdev_port_poll(const struct dpif
*dpif_
, char **devnamep OVS_UNUSED
)
997 struct dpif_netdev
*dpif
= dpif_netdev_cast(dpif_
);
998 uint64_t new_port_seq
;
1001 new_port_seq
= seq_read(dpif
->dp
->port_seq
);
1002 if (dpif
->last_port_seq
!= new_port_seq
) {
1003 dpif
->last_port_seq
= new_port_seq
;
1013 dpif_netdev_port_poll_wait(const struct dpif
*dpif_
)
1015 struct dpif_netdev
*dpif
= dpif_netdev_cast(dpif_
);
1017 seq_wait(dpif
->dp
->port_seq
, dpif
->last_port_seq
);
1020 static struct dp_netdev_flow
*
1021 dp_netdev_flow_cast(const struct cls_rule
*cr
)
1023 return cr
? CONTAINER_OF(cr
, struct dp_netdev_flow
, cr
) : NULL
;
1026 static struct dp_netdev_flow
*
1027 dp_netdev_lookup_flow(const struct dp_netdev
*dp
, const struct miniflow
*key
)
1029 struct dp_netdev_flow
*netdev_flow
;
1030 struct cls_rule
*rule
;
1032 classifier_lookup_miniflow_batch(&dp
->cls
, &key
, &rule
, 1);
1033 netdev_flow
= dp_netdev_flow_cast(rule
);
1038 static struct dp_netdev_flow
*
1039 dp_netdev_find_flow(const struct dp_netdev
*dp
, const struct flow
*flow
)
1041 struct dp_netdev_flow
*netdev_flow
;
1043 CMAP_FOR_EACH_WITH_HASH (netdev_flow
, node
, flow_hash(flow
, 0),
1045 if (flow_equal(&netdev_flow
->flow
, flow
)) {
1054 get_dpif_flow_stats(const struct dp_netdev_flow
*netdev_flow
,
1055 struct dpif_flow_stats
*stats
)
1057 struct dp_netdev_flow_stats
*bucket
;
1060 memset(stats
, 0, sizeof *stats
);
1061 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &netdev_flow
->stats
) {
1062 ovs_mutex_lock(&bucket
->mutex
);
1063 stats
->n_packets
+= bucket
->packet_count
;
1064 stats
->n_bytes
+= bucket
->byte_count
;
1065 stats
->used
= MAX(stats
->used
, bucket
->used
);
1066 stats
->tcp_flags
|= bucket
->tcp_flags
;
1067 ovs_mutex_unlock(&bucket
->mutex
);
1072 dp_netdev_flow_to_dpif_flow(const struct dp_netdev_flow
*netdev_flow
,
1073 struct ofpbuf
*buffer
, struct dpif_flow
*flow
)
1075 struct flow_wildcards wc
;
1076 struct dp_netdev_actions
*actions
;
1078 minimask_expand(&netdev_flow
->cr
.match
.mask
, &wc
);
1079 odp_flow_key_from_mask(buffer
, &wc
.masks
, &netdev_flow
->flow
,
1080 odp_to_u32(wc
.masks
.in_port
.odp_port
),
1082 flow
->mask
= ofpbuf_data(buffer
);
1083 flow
->mask_len
= ofpbuf_size(buffer
);
1085 actions
= dp_netdev_flow_get_actions(netdev_flow
);
1086 flow
->actions
= actions
->actions
;
1087 flow
->actions_len
= actions
->size
;
1089 get_dpif_flow_stats(netdev_flow
, &flow
->stats
);
1093 dpif_netdev_mask_from_nlattrs(const struct nlattr
*key
, uint32_t key_len
,
1094 const struct nlattr
*mask_key
,
1095 uint32_t mask_key_len
, const struct flow
*flow
,
1099 enum odp_key_fitness fitness
;
1101 fitness
= odp_flow_key_to_mask(mask_key
, mask_key_len
, mask
, flow
);
1103 /* This should not happen: it indicates that
1104 * odp_flow_key_from_mask() and odp_flow_key_to_mask()
1105 * disagree on the acceptable form of a mask. Log the problem
1106 * as an error, with enough details to enable debugging. */
1107 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
1109 if (!VLOG_DROP_ERR(&rl
)) {
1113 odp_flow_format(key
, key_len
, mask_key
, mask_key_len
, NULL
, &s
,
1115 VLOG_ERR("internal error parsing flow mask %s (%s)",
1116 ds_cstr(&s
), odp_key_fitness_to_string(fitness
));
1123 enum mf_field_id id
;
1124 /* No mask key, unwildcard everything except fields whose
1125 * prerequisities are not met. */
1126 memset(mask
, 0x0, sizeof *mask
);
1128 for (id
= 0; id
< MFF_N_IDS
; ++id
) {
1129 /* Skip registers and metadata. */
1130 if (!(id
>= MFF_REG0
&& id
< MFF_REG0
+ FLOW_N_REGS
)
1131 && id
!= MFF_METADATA
) {
1132 const struct mf_field
*mf
= mf_from_id(id
);
1133 if (mf_are_prereqs_ok(mf
, flow
)) {
1134 mf_mask_field(mf
, mask
);
1140 /* Force unwildcard the in_port.
1142 * We need to do this even in the case where we unwildcard "everything"
1143 * above because "everything" only includes the 16-bit OpenFlow port number
1144 * mask->in_port.ofp_port, which only covers half of the 32-bit datapath
1145 * port number mask->in_port.odp_port. */
1146 mask
->in_port
.odp_port
= u32_to_odp(UINT32_MAX
);
1152 dpif_netdev_flow_from_nlattrs(const struct nlattr
*key
, uint32_t key_len
,
1157 if (odp_flow_key_to_flow(key
, key_len
, flow
)) {
1158 /* This should not happen: it indicates that odp_flow_key_from_flow()
1159 * and odp_flow_key_to_flow() disagree on the acceptable form of a
1160 * flow. Log the problem as an error, with enough details to enable
1162 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
1164 if (!VLOG_DROP_ERR(&rl
)) {
1168 odp_flow_format(key
, key_len
, NULL
, 0, NULL
, &s
, true);
1169 VLOG_ERR("internal error parsing flow key %s", ds_cstr(&s
));
1176 in_port
= flow
->in_port
.odp_port
;
1177 if (!is_valid_port_number(in_port
) && in_port
!= ODPP_NONE
) {
1185 dpif_netdev_flow_get(const struct dpif
*dpif
, const struct dpif_flow_get
*get
)
1187 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1188 struct dp_netdev_flow
*netdev_flow
;
1192 error
= dpif_netdev_flow_from_nlattrs(get
->key
, get
->key_len
, &key
);
1197 netdev_flow
= dp_netdev_find_flow(dp
, &key
);
1200 dp_netdev_flow_to_dpif_flow(netdev_flow
, get
->buffer
, get
->flow
);
1209 dp_netdev_flow_add(struct dp_netdev
*dp
, struct match
*match
,
1210 const struct nlattr
*actions
, size_t actions_len
)
1211 OVS_REQUIRES(dp
->flow_mutex
)
1213 struct dp_netdev_flow
*netdev_flow
;
1215 netdev_flow
= xzalloc(sizeof *netdev_flow
);
1216 *CONST_CAST(struct flow
*, &netdev_flow
->flow
) = match
->flow
;
1218 ovs_refcount_init(&netdev_flow
->ref_cnt
);
1220 ovsthread_stats_init(&netdev_flow
->stats
);
1222 ovsrcu_set(&netdev_flow
->actions
,
1223 dp_netdev_actions_create(actions
, actions_len
));
1225 cls_rule_init(CONST_CAST(struct cls_rule
*, &netdev_flow
->cr
),
1226 match
, NETDEV_RULE_PRIORITY
);
1227 cmap_insert(&dp
->flow_table
,
1228 CONST_CAST(struct cmap_node
*, &netdev_flow
->node
),
1229 flow_hash(&match
->flow
, 0));
1230 classifier_insert(&dp
->cls
,
1231 CONST_CAST(struct cls_rule
*, &netdev_flow
->cr
));
1233 if (OVS_UNLIKELY(VLOG_IS_DBG_ENABLED())) {
1234 struct ds ds
= DS_EMPTY_INITIALIZER
;
1236 ds_put_cstr(&ds
, "flow_add: ");
1237 match_format(match
, &ds
, OFP_DEFAULT_PRIORITY
);
1238 ds_put_cstr(&ds
, ", actions:");
1239 format_odp_actions(&ds
, actions
, actions_len
);
1241 VLOG_DBG_RL(&upcall_rl
, "%s", ds_cstr(&ds
));
1250 clear_stats(struct dp_netdev_flow
*netdev_flow
)
1252 struct dp_netdev_flow_stats
*bucket
;
1255 OVSTHREAD_STATS_FOR_EACH_BUCKET (bucket
, i
, &netdev_flow
->stats
) {
1256 ovs_mutex_lock(&bucket
->mutex
);
1258 bucket
->packet_count
= 0;
1259 bucket
->byte_count
= 0;
1260 bucket
->tcp_flags
= 0;
1261 ovs_mutex_unlock(&bucket
->mutex
);
1266 dpif_netdev_flow_put(struct dpif
*dpif
, const struct dpif_flow_put
*put
)
1268 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1269 struct dp_netdev_flow
*netdev_flow
;
1270 struct miniflow miniflow
;
1274 error
= dpif_netdev_flow_from_nlattrs(put
->key
, put
->key_len
, &match
.flow
);
1278 error
= dpif_netdev_mask_from_nlattrs(put
->key
, put
->key_len
,
1279 put
->mask
, put
->mask_len
,
1280 &match
.flow
, &match
.wc
.masks
);
1284 miniflow_init(&miniflow
, &match
.flow
);
1286 ovs_mutex_lock(&dp
->flow_mutex
);
1287 netdev_flow
= dp_netdev_lookup_flow(dp
, &miniflow
);
1289 if (put
->flags
& DPIF_FP_CREATE
) {
1290 if (cmap_count(&dp
->flow_table
) < MAX_FLOWS
) {
1292 memset(put
->stats
, 0, sizeof *put
->stats
);
1294 error
= dp_netdev_flow_add(dp
, &match
, put
->actions
,
1303 if (put
->flags
& DPIF_FP_MODIFY
1304 && flow_equal(&match
.flow
, &netdev_flow
->flow
)) {
1305 struct dp_netdev_actions
*new_actions
;
1306 struct dp_netdev_actions
*old_actions
;
1308 new_actions
= dp_netdev_actions_create(put
->actions
,
1311 old_actions
= dp_netdev_flow_get_actions(netdev_flow
);
1312 ovsrcu_set(&netdev_flow
->actions
, new_actions
);
1315 get_dpif_flow_stats(netdev_flow
, put
->stats
);
1317 if (put
->flags
& DPIF_FP_ZERO_STATS
) {
1318 clear_stats(netdev_flow
);
1321 ovsrcu_postpone(dp_netdev_actions_free
, old_actions
);
1322 } else if (put
->flags
& DPIF_FP_CREATE
) {
1325 /* Overlapping flow. */
1329 ovs_mutex_unlock(&dp
->flow_mutex
);
1330 miniflow_destroy(&miniflow
);
1336 dpif_netdev_flow_del(struct dpif
*dpif
, const struct dpif_flow_del
*del
)
1338 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1339 struct dp_netdev_flow
*netdev_flow
;
1343 error
= dpif_netdev_flow_from_nlattrs(del
->key
, del
->key_len
, &key
);
1348 ovs_mutex_lock(&dp
->flow_mutex
);
1349 netdev_flow
= dp_netdev_find_flow(dp
, &key
);
1352 get_dpif_flow_stats(netdev_flow
, del
->stats
);
1354 dp_netdev_remove_flow(dp
, netdev_flow
);
1358 ovs_mutex_unlock(&dp
->flow_mutex
);
1363 struct dpif_netdev_flow_dump
{
1364 struct dpif_flow_dump up
;
1365 struct cmap_position pos
;
1367 struct ovs_mutex mutex
;
1370 static struct dpif_netdev_flow_dump
*
1371 dpif_netdev_flow_dump_cast(struct dpif_flow_dump
*dump
)
1373 return CONTAINER_OF(dump
, struct dpif_netdev_flow_dump
, up
);
1376 static struct dpif_flow_dump
*
1377 dpif_netdev_flow_dump_create(const struct dpif
*dpif_
)
1379 struct dpif_netdev_flow_dump
*dump
;
1381 dump
= xmalloc(sizeof *dump
);
1382 dpif_flow_dump_init(&dump
->up
, dpif_
);
1383 memset(&dump
->pos
, 0, sizeof dump
->pos
);
1385 ovs_mutex_init(&dump
->mutex
);
1391 dpif_netdev_flow_dump_destroy(struct dpif_flow_dump
*dump_
)
1393 struct dpif_netdev_flow_dump
*dump
= dpif_netdev_flow_dump_cast(dump_
);
1395 ovs_mutex_destroy(&dump
->mutex
);
1400 struct dpif_netdev_flow_dump_thread
{
1401 struct dpif_flow_dump_thread up
;
1402 struct dpif_netdev_flow_dump
*dump
;
1403 struct odputil_keybuf keybuf
[FLOW_DUMP_MAX_BATCH
];
1404 struct odputil_keybuf maskbuf
[FLOW_DUMP_MAX_BATCH
];
1407 static struct dpif_netdev_flow_dump_thread
*
1408 dpif_netdev_flow_dump_thread_cast(struct dpif_flow_dump_thread
*thread
)
1410 return CONTAINER_OF(thread
, struct dpif_netdev_flow_dump_thread
, up
);
1413 static struct dpif_flow_dump_thread
*
1414 dpif_netdev_flow_dump_thread_create(struct dpif_flow_dump
*dump_
)
1416 struct dpif_netdev_flow_dump
*dump
= dpif_netdev_flow_dump_cast(dump_
);
1417 struct dpif_netdev_flow_dump_thread
*thread
;
1419 thread
= xmalloc(sizeof *thread
);
1420 dpif_flow_dump_thread_init(&thread
->up
, &dump
->up
);
1421 thread
->dump
= dump
;
1426 dpif_netdev_flow_dump_thread_destroy(struct dpif_flow_dump_thread
*thread_
)
1428 struct dpif_netdev_flow_dump_thread
*thread
1429 = dpif_netdev_flow_dump_thread_cast(thread_
);
1435 dpif_netdev_flow_dump_next(struct dpif_flow_dump_thread
*thread_
,
1436 struct dpif_flow
*flows
, int max_flows
)
1438 struct dpif_netdev_flow_dump_thread
*thread
1439 = dpif_netdev_flow_dump_thread_cast(thread_
);
1440 struct dpif_netdev_flow_dump
*dump
= thread
->dump
;
1441 struct dpif_netdev
*dpif
= dpif_netdev_cast(thread
->up
.dpif
);
1442 struct dp_netdev_flow
*netdev_flows
[FLOW_DUMP_MAX_BATCH
];
1443 struct dp_netdev
*dp
= get_dp_netdev(&dpif
->dpif
);
1447 ovs_mutex_lock(&dump
->mutex
);
1448 if (!dump
->status
) {
1449 for (n_flows
= 0; n_flows
< MIN(max_flows
, FLOW_DUMP_MAX_BATCH
);
1451 struct cmap_node
*node
;
1453 node
= cmap_next_position(&dp
->flow_table
, &dump
->pos
);
1458 netdev_flows
[n_flows
] = CONTAINER_OF(node
, struct dp_netdev_flow
,
1462 ovs_mutex_unlock(&dump
->mutex
);
1464 for (i
= 0; i
< n_flows
; i
++) {
1465 struct odputil_keybuf
*maskbuf
= &thread
->maskbuf
[i
];
1466 struct odputil_keybuf
*keybuf
= &thread
->keybuf
[i
];
1467 struct dp_netdev_flow
*netdev_flow
= netdev_flows
[i
];
1468 struct dpif_flow
*f
= &flows
[i
];
1469 struct dp_netdev_actions
*dp_actions
;
1470 struct flow_wildcards wc
;
1473 minimask_expand(&netdev_flow
->cr
.match
.mask
, &wc
);
1476 ofpbuf_use_stack(&buf
, keybuf
, sizeof *keybuf
);
1477 odp_flow_key_from_flow(&buf
, &netdev_flow
->flow
, &wc
.masks
,
1478 netdev_flow
->flow
.in_port
.odp_port
, true);
1479 f
->key
= ofpbuf_data(&buf
);
1480 f
->key_len
= ofpbuf_size(&buf
);
1483 ofpbuf_use_stack(&buf
, maskbuf
, sizeof *maskbuf
);
1484 odp_flow_key_from_mask(&buf
, &wc
.masks
, &netdev_flow
->flow
,
1485 odp_to_u32(wc
.masks
.in_port
.odp_port
),
1487 f
->mask
= ofpbuf_data(&buf
);
1488 f
->mask_len
= ofpbuf_size(&buf
);
1491 dp_actions
= dp_netdev_flow_get_actions(netdev_flow
);
1492 f
->actions
= dp_actions
->actions
;
1493 f
->actions_len
= dp_actions
->size
;
1496 get_dpif_flow_stats(netdev_flow
, &f
->stats
);
1503 dpif_netdev_execute(struct dpif
*dpif
, struct dpif_execute
*execute
)
1505 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1506 struct dpif_packet packet
, *pp
;
1507 struct pkt_metadata
*md
= &execute
->md
;
1509 if (ofpbuf_size(execute
->packet
) < ETH_HEADER_LEN
||
1510 ofpbuf_size(execute
->packet
) > UINT16_MAX
) {
1514 packet
.ofpbuf
= *execute
->packet
;
1517 dp_netdev_execute_actions(dp
, &pp
, 1, false, md
,
1518 execute
->actions
, execute
->actions_len
);
1520 /* Even though may_steal is set to false, some actions could modify or
1521 * reallocate the ofpbuf memory. We need to pass those changes to the
1523 *execute
->packet
= packet
.ofpbuf
;
1529 dpif_netdev_operate(struct dpif
*dpif
, struct dpif_op
**ops
, size_t n_ops
)
1533 for (i
= 0; i
< n_ops
; i
++) {
1534 struct dpif_op
*op
= ops
[i
];
1537 case DPIF_OP_FLOW_PUT
:
1538 op
->error
= dpif_netdev_flow_put(dpif
, &op
->u
.flow_put
);
1541 case DPIF_OP_FLOW_DEL
:
1542 op
->error
= dpif_netdev_flow_del(dpif
, &op
->u
.flow_del
);
1545 case DPIF_OP_EXECUTE
:
1546 op
->error
= dpif_netdev_execute(dpif
, &op
->u
.execute
);
1549 case DPIF_OP_FLOW_GET
:
1550 op
->error
= dpif_netdev_flow_get(dpif
, &op
->u
.flow_get
);
1557 dpif_netdev_queue_to_priority(const struct dpif
*dpif OVS_UNUSED
,
1558 uint32_t queue_id
, uint32_t *priority
)
1560 *priority
= queue_id
;
1565 /* Creates and returns a new 'struct dp_netdev_actions', with a reference count
1566 * of 1, whose actions are a copy of from the 'ofpacts_len' bytes of
1568 struct dp_netdev_actions
*
1569 dp_netdev_actions_create(const struct nlattr
*actions
, size_t size
)
1571 struct dp_netdev_actions
*netdev_actions
;
1573 netdev_actions
= xmalloc(sizeof *netdev_actions
);
1574 netdev_actions
->actions
= xmemdup(actions
, size
);
1575 netdev_actions
->size
= size
;
1577 return netdev_actions
;
1580 struct dp_netdev_actions
*
1581 dp_netdev_flow_get_actions(const struct dp_netdev_flow
*flow
)
1583 return ovsrcu_get(struct dp_netdev_actions
*, &flow
->actions
);
1587 dp_netdev_actions_free(struct dp_netdev_actions
*actions
)
1589 free(actions
->actions
);
1595 dp_netdev_process_rxq_port(struct dp_netdev
*dp
,
1596 struct dp_netdev_port
*port
,
1597 struct netdev_rxq
*rxq
)
1599 struct dpif_packet
*packets
[NETDEV_MAX_RX_BATCH
];
1602 error
= netdev_rxq_recv(rxq
, packets
, &cnt
);
1604 dp_netdev_port_input(dp
, packets
, cnt
, port
->port_no
);
1605 } else if (error
!= EAGAIN
&& error
!= EOPNOTSUPP
) {
1606 static struct vlog_rate_limit rl
1607 = VLOG_RATE_LIMIT_INIT(1, 5);
1609 VLOG_ERR_RL(&rl
, "error receiving data from %s: %s",
1610 netdev_get_name(port
->netdev
),
1611 ovs_strerror(error
));
1616 dpif_netdev_run(struct dpif
*dpif
)
1618 struct dp_netdev_port
*port
;
1619 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1621 CMAP_FOR_EACH (port
, node
, &dp
->ports
) {
1622 if (!netdev_is_pmd(port
->netdev
)) {
1625 for (i
= 0; i
< netdev_n_rxq(port
->netdev
); i
++) {
1626 dp_netdev_process_rxq_port(dp
, port
, port
->rxq
[i
]);
1633 dpif_netdev_wait(struct dpif
*dpif
)
1635 struct dp_netdev_port
*port
;
1636 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1638 ovs_mutex_lock(&dp_netdev_mutex
);
1639 CMAP_FOR_EACH (port
, node
, &dp
->ports
) {
1640 if (!netdev_is_pmd(port
->netdev
)) {
1643 for (i
= 0; i
< netdev_n_rxq(port
->netdev
); i
++) {
1644 netdev_rxq_wait(port
->rxq
[i
]);
1648 ovs_mutex_unlock(&dp_netdev_mutex
);
1652 struct dp_netdev_port
*port
;
1653 struct netdev_rxq
*rx
;
1657 pmd_load_queues(struct pmd_thread
*f
,
1658 struct rxq_poll
**ppoll_list
, int poll_cnt
)
1660 struct dp_netdev
*dp
= f
->dp
;
1661 struct rxq_poll
*poll_list
= *ppoll_list
;
1662 struct dp_netdev_port
*port
;
1667 /* Simple scheduler for netdev rx polling. */
1668 for (i
= 0; i
< poll_cnt
; i
++) {
1669 port_unref(poll_list
[i
].port
);
1675 CMAP_FOR_EACH (port
, node
, &f
->dp
->ports
) {
1676 if (netdev_is_pmd(port
->netdev
)) {
1679 for (i
= 0; i
< netdev_n_rxq(port
->netdev
); i
++) {
1680 if ((index
% dp
->n_pmd_threads
) == id
) {
1681 poll_list
= xrealloc(poll_list
, sizeof *poll_list
* (poll_cnt
+ 1));
1684 poll_list
[poll_cnt
].port
= port
;
1685 poll_list
[poll_cnt
].rx
= port
->rxq
[i
];
1693 *ppoll_list
= poll_list
;
1698 pmd_thread_main(void *f_
)
1700 struct pmd_thread
*f
= f_
;
1701 struct dp_netdev
*dp
= f
->dp
;
1702 unsigned int lc
= 0;
1703 struct rxq_poll
*poll_list
;
1704 unsigned int port_seq
;
1711 pmd_thread_setaffinity_cpu(f
->id
);
1713 poll_cnt
= pmd_load_queues(f
, &poll_list
, poll_cnt
);
1714 atomic_read(&f
->change_seq
, &port_seq
);
1717 unsigned int c_port_seq
;
1720 for (i
= 0; i
< poll_cnt
; i
++) {
1721 dp_netdev_process_rxq_port(dp
, poll_list
[i
].port
, poll_list
[i
].rx
);
1727 /* XXX: need completely userspace based signaling method.
1728 * to keep this thread entirely in userspace.
1729 * For now using atomic counter. */
1731 atomic_read_explicit(&f
->change_seq
, &c_port_seq
, memory_order_consume
);
1732 if (c_port_seq
!= port_seq
) {
1738 if (!latch_is_set(&f
->dp
->exit_latch
)){
1742 for (i
= 0; i
< poll_cnt
; i
++) {
1743 port_unref(poll_list
[i
].port
);
1751 dp_netdev_disable_upcall(struct dp_netdev
*dp
)
1752 OVS_ACQUIRES(dp
->upcall_rwlock
)
1754 fat_rwlock_wrlock(&dp
->upcall_rwlock
);
1758 dpif_netdev_disable_upcall(struct dpif
*dpif
)
1759 OVS_NO_THREAD_SAFETY_ANALYSIS
1761 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1762 dp_netdev_disable_upcall(dp
);
1766 dp_netdev_enable_upcall(struct dp_netdev
*dp
)
1767 OVS_RELEASES(dp
->upcall_rwlock
)
1769 fat_rwlock_unlock(&dp
->upcall_rwlock
);
1773 dpif_netdev_enable_upcall(struct dpif
*dpif
)
1774 OVS_NO_THREAD_SAFETY_ANALYSIS
1776 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
1777 dp_netdev_enable_upcall(dp
);
1781 dp_netdev_set_pmd_threads(struct dp_netdev
*dp
, int n
)
1785 if (n
== dp
->n_pmd_threads
) {
1789 /* Stop existing threads. */
1790 latch_set(&dp
->exit_latch
);
1791 dp_netdev_reload_pmd_threads(dp
);
1792 for (i
= 0; i
< dp
->n_pmd_threads
; i
++) {
1793 struct pmd_thread
*f
= &dp
->pmd_threads
[i
];
1795 xpthread_join(f
->thread
, NULL
);
1797 latch_poll(&dp
->exit_latch
);
1798 free(dp
->pmd_threads
);
1800 /* Start new threads. */
1801 dp
->pmd_threads
= xmalloc(n
* sizeof *dp
->pmd_threads
);
1802 dp
->n_pmd_threads
= n
;
1804 for (i
= 0; i
< n
; i
++) {
1805 struct pmd_thread
*f
= &dp
->pmd_threads
[i
];
1809 atomic_store(&f
->change_seq
, 1);
1811 /* Each thread will distribute all devices rx-queues among
1813 f
->thread
= ovs_thread_create("pmd", pmd_thread_main
, f
);
1819 dp_netdev_flow_stats_new_cb(void)
1821 struct dp_netdev_flow_stats
*bucket
= xzalloc_cacheline(sizeof *bucket
);
1822 ovs_mutex_init(&bucket
->mutex
);
1827 dp_netdev_flow_used(struct dp_netdev_flow
*netdev_flow
,
1831 long long int now
= time_msec();
1832 struct dp_netdev_flow_stats
*bucket
;
1834 bucket
= ovsthread_stats_bucket_get(&netdev_flow
->stats
,
1835 dp_netdev_flow_stats_new_cb
);
1837 ovs_mutex_lock(&bucket
->mutex
);
1838 bucket
->used
= MAX(now
, bucket
->used
);
1839 bucket
->packet_count
+= cnt
;
1840 bucket
->byte_count
+= size
;
1841 bucket
->tcp_flags
|= tcp_flags
;
1842 ovs_mutex_unlock(&bucket
->mutex
);
1846 dp_netdev_stats_new_cb(void)
1848 struct dp_netdev_stats
*bucket
= xzalloc_cacheline(sizeof *bucket
);
1849 ovs_mutex_init(&bucket
->mutex
);
1854 dp_netdev_count_packet(struct dp_netdev
*dp
, enum dp_stat_type type
, int cnt
)
1856 struct dp_netdev_stats
*bucket
;
1858 bucket
= ovsthread_stats_bucket_get(&dp
->stats
, dp_netdev_stats_new_cb
);
1859 ovs_mutex_lock(&bucket
->mutex
);
1860 bucket
->n
[type
] += cnt
;
1861 ovs_mutex_unlock(&bucket
->mutex
);
1865 dp_netdev_upcall(struct dp_netdev
*dp
, struct dpif_packet
*packet_
,
1866 struct flow
*flow
, struct flow_wildcards
*wc
,
1867 enum dpif_upcall_type type
, const struct nlattr
*userdata
,
1868 struct ofpbuf
*actions
, struct ofpbuf
*put_actions
)
1870 struct ofpbuf
*packet
= &packet_
->ofpbuf
;
1872 if (type
== DPIF_UC_MISS
) {
1873 dp_netdev_count_packet(dp
, DP_STAT_MISS
, 1);
1876 if (OVS_UNLIKELY(!dp
->upcall_cb
)) {
1880 if (OVS_UNLIKELY(!VLOG_DROP_DBG(&upcall_rl
))) {
1881 struct ds ds
= DS_EMPTY_INITIALIZER
;
1885 ofpbuf_init(&key
, 0);
1886 odp_flow_key_from_flow(&key
, flow
, &wc
->masks
, flow
->in_port
.odp_port
,
1889 packet_str
= ofp_packet_to_string(ofpbuf_data(packet
),
1890 ofpbuf_size(packet
));
1892 odp_flow_key_format(ofpbuf_data(&key
), ofpbuf_size(&key
), &ds
);
1894 VLOG_DBG("%s: %s upcall:\n%s\n%s", dp
->name
,
1895 dpif_upcall_type_to_string(type
), ds_cstr(&ds
), packet_str
);
1897 ofpbuf_uninit(&key
);
1902 return dp
->upcall_cb(packet
, flow
, type
, userdata
, actions
, wc
,
1903 put_actions
, dp
->upcall_aux
);
1906 struct packet_batch
{
1907 unsigned int packet_count
;
1908 unsigned int byte_count
;
1911 struct dp_netdev_flow
*flow
;
1913 struct dpif_packet
*packets
[NETDEV_MAX_RX_BATCH
];
1914 struct pkt_metadata md
;
1918 packet_batch_update(struct packet_batch
*batch
,
1919 struct dpif_packet
*packet
, const struct miniflow
*mf
)
1921 batch
->tcp_flags
|= miniflow_get_tcp_flags(mf
);
1922 batch
->packets
[batch
->packet_count
++] = packet
;
1923 batch
->byte_count
+= ofpbuf_size(&packet
->ofpbuf
);
1927 packet_batch_init(struct packet_batch
*batch
, struct dp_netdev_flow
*flow
,
1928 struct pkt_metadata
*md
)
1933 batch
->packet_count
= 0;
1934 batch
->byte_count
= 0;
1935 batch
->tcp_flags
= 0;
1939 packet_batch_execute(struct packet_batch
*batch
, struct dp_netdev
*dp
)
1941 struct dp_netdev_actions
*actions
;
1942 struct dp_netdev_flow
*flow
= batch
->flow
;
1944 dp_netdev_flow_used(batch
->flow
, batch
->packet_count
, batch
->byte_count
,
1947 actions
= dp_netdev_flow_get_actions(flow
);
1949 dp_netdev_execute_actions(dp
, batch
->packets
,
1950 batch
->packet_count
, true, &batch
->md
,
1951 actions
->actions
, actions
->size
);
1953 dp_netdev_count_packet(dp
, DP_STAT_HIT
, batch
->packet_count
);
1957 dp_netdev_input(struct dp_netdev
*dp
, struct dpif_packet
**packets
, int cnt
,
1958 struct pkt_metadata
*md
)
1960 struct packet_batch batches
[NETDEV_MAX_RX_BATCH
];
1961 struct netdev_flow_key keys
[NETDEV_MAX_RX_BATCH
];
1962 const struct miniflow
*mfs
[NETDEV_MAX_RX_BATCH
]; /* NULL at bad packets. */
1963 struct cls_rule
*rules
[NETDEV_MAX_RX_BATCH
];
1964 size_t n_batches
, i
;
1967 for (i
= 0; i
< cnt
; i
++) {
1968 if (OVS_UNLIKELY(ofpbuf_size(&packets
[i
]->ofpbuf
) < ETH_HEADER_LEN
)) {
1969 dpif_packet_delete(packets
[i
]);
1974 miniflow_initialize(&keys
[i
].flow
, keys
[i
].buf
);
1975 miniflow_extract(&packets
[i
]->ofpbuf
, md
, &keys
[i
].flow
);
1976 mfs
[i
] = &keys
[i
].flow
;
1979 any_miss
= !classifier_lookup_miniflow_batch(&dp
->cls
, mfs
, rules
, cnt
);
1980 if (OVS_UNLIKELY(any_miss
) && !fat_rwlock_tryrdlock(&dp
->upcall_rwlock
)) {
1981 uint64_t actions_stub
[512 / 8], slow_stub
[512 / 8];
1982 struct ofpbuf actions
, put_actions
;
1985 ofpbuf_use_stub(&actions
, actions_stub
, sizeof actions_stub
);
1986 ofpbuf_use_stub(&put_actions
, slow_stub
, sizeof slow_stub
);
1988 for (i
= 0; i
< cnt
; i
++) {
1989 const struct dp_netdev_flow
*netdev_flow
;
1990 struct ofpbuf
*add_actions
;
1993 if (OVS_LIKELY(rules
[i
] || !mfs
[i
])) {
1997 /* It's possible that an earlier slow path execution installed
1998 * the rule this flow needs. In this case, it's a lot cheaper
1999 * to catch it here than execute a miss. */
2000 netdev_flow
= dp_netdev_lookup_flow(dp
, mfs
[i
]);
2002 rules
[i
] = CONST_CAST(struct cls_rule
*, &netdev_flow
->cr
);
2006 miniflow_expand(mfs
[i
], &match
.flow
);
2008 ofpbuf_clear(&actions
);
2009 ofpbuf_clear(&put_actions
);
2011 error
= dp_netdev_upcall(dp
, packets
[i
], &match
.flow
, &match
.wc
,
2012 DPIF_UC_MISS
, NULL
, &actions
,
2014 if (OVS_UNLIKELY(error
&& error
!= ENOSPC
)) {
2018 /* We can't allow the packet batching in the next loop to execute
2019 * the actions. Otherwise, if there are any slow path actions,
2020 * we'll send the packet up twice. */
2021 dp_netdev_execute_actions(dp
, &packets
[i
], 1, false, md
,
2022 ofpbuf_data(&actions
),
2023 ofpbuf_size(&actions
));
2025 add_actions
= ofpbuf_size(&put_actions
)
2029 ovs_mutex_lock(&dp
->flow_mutex
);
2030 /* XXX: There's a brief race where this flow could have already
2031 * been installed since we last did the flow lookup. This could be
2032 * solved by moving the mutex lock outside the loop, but that's an
2033 * awful long time to be locking everyone out of making flow
2034 * installs. If we move to a per-core classifier, it would be
2036 if (OVS_LIKELY(error
!= ENOSPC
)
2037 && !dp_netdev_lookup_flow(dp
, mfs
[i
])) {
2038 dp_netdev_flow_add(dp
, &match
, ofpbuf_data(add_actions
),
2039 ofpbuf_size(add_actions
));
2041 ovs_mutex_unlock(&dp
->flow_mutex
);
2044 ofpbuf_uninit(&actions
);
2045 ofpbuf_uninit(&put_actions
);
2046 fat_rwlock_unlock(&dp
->upcall_rwlock
);
2050 for (i
= 0; i
< cnt
; i
++) {
2051 struct dp_netdev_flow
*flow
;
2052 struct packet_batch
*batch
;
2055 if (OVS_UNLIKELY(!rules
[i
] || !mfs
[i
])) {
2059 /* XXX: This O(n^2) algortihm makes sense if we're operating under the
2060 * assumption that the number of distinct flows (and therefore the
2061 * number of distinct batches) is quite small. If this turns out not
2062 * to be the case, it may make sense to pre sort based on the
2063 * netdev_flow pointer. That done we can get the appropriate batching
2064 * in O(n * log(n)) instead. */
2066 flow
= dp_netdev_flow_cast(rules
[i
]);
2067 for (j
= 0; j
< n_batches
; j
++) {
2068 if (batches
[j
].flow
== flow
) {
2069 batch
= &batches
[j
];
2075 batch
= &batches
[n_batches
++];
2076 packet_batch_init(batch
, flow
, md
);
2078 packet_batch_update(batch
, packets
[i
], mfs
[i
]);
2081 for (i
= 0; i
< n_batches
; i
++) {
2082 packet_batch_execute(&batches
[i
], dp
);
2087 dp_netdev_port_input(struct dp_netdev
*dp
, struct dpif_packet
**packets
,
2088 int cnt
, odp_port_t port_no
)
2090 uint32_t *recirc_depth
= recirc_depth_get();
2091 struct pkt_metadata md
= PKT_METADATA_INITIALIZER(port_no
);
2094 dp_netdev_input(dp
, packets
, cnt
, &md
);
2097 struct dp_netdev_execute_aux
{
2098 struct dp_netdev
*dp
;
2102 dpif_netdev_register_upcall_cb(struct dpif
*dpif
, upcall_callback
*cb
,
2105 struct dp_netdev
*dp
= get_dp_netdev(dpif
);
2106 dp
->upcall_aux
= aux
;
2111 dp_execute_cb(void *aux_
, struct dpif_packet
**packets
, int cnt
,
2112 struct pkt_metadata
*md
,
2113 const struct nlattr
*a
, bool may_steal
)
2114 OVS_NO_THREAD_SAFETY_ANALYSIS
2116 struct dp_netdev_execute_aux
*aux
= aux_
;
2117 uint32_t *depth
= recirc_depth_get();
2118 struct dp_netdev
*dp
= aux
->dp
;
2119 int type
= nl_attr_type(a
);
2120 struct dp_netdev_port
*p
;
2123 switch ((enum ovs_action_attr
)type
) {
2124 case OVS_ACTION_ATTR_OUTPUT
:
2125 p
= dp_netdev_lookup_port(dp
, u32_to_odp(nl_attr_get_u32(a
)));
2126 if (OVS_LIKELY(p
)) {
2127 netdev_send(p
->netdev
, packets
, cnt
, may_steal
);
2128 } else if (may_steal
) {
2129 for (i
= 0; i
< cnt
; i
++) {
2130 dpif_packet_delete(packets
[i
]);
2135 case OVS_ACTION_ATTR_USERSPACE
:
2136 if (!fat_rwlock_tryrdlock(&dp
->upcall_rwlock
)) {
2137 const struct nlattr
*userdata
;
2138 struct ofpbuf actions
;
2141 userdata
= nl_attr_find_nested(a
, OVS_USERSPACE_ATTR_USERDATA
);
2142 ofpbuf_init(&actions
, 0);
2144 for (i
= 0; i
< cnt
; i
++) {
2147 ofpbuf_clear(&actions
);
2149 flow_extract(&packets
[i
]->ofpbuf
, md
, &flow
);
2150 error
= dp_netdev_upcall(dp
, packets
[i
], &flow
, NULL
,
2151 DPIF_UC_ACTION
, userdata
, &actions
,
2153 if (!error
|| error
== ENOSPC
) {
2154 dp_netdev_execute_actions(dp
, &packets
[i
], 1, false, md
,
2155 ofpbuf_data(&actions
),
2156 ofpbuf_size(&actions
));
2160 dpif_packet_delete(packets
[i
]);
2163 ofpbuf_uninit(&actions
);
2164 fat_rwlock_unlock(&dp
->upcall_rwlock
);
2169 case OVS_ACTION_ATTR_HASH
: {
2170 const struct ovs_action_hash
*hash_act
;
2171 struct netdev_flow_key key
;
2174 hash_act
= nl_attr_get(a
);
2176 miniflow_initialize(&key
.flow
, key
.buf
);
2178 for (i
= 0; i
< cnt
; i
++) {
2180 /* XXX: this is slow. Use RSS hash in the future */
2181 miniflow_extract(&packets
[i
]->ofpbuf
, md
, &key
.flow
);
2183 if (hash_act
->hash_alg
== OVS_HASH_ALG_L4
) {
2184 /* Hash need not be symmetric, nor does it need to include
2186 hash
= miniflow_hash_5tuple(&key
.flow
, hash_act
->hash_basis
);
2188 VLOG_WARN("Unknown hash algorithm specified "
2189 "for the hash action.");
2194 hash
= 1; /* 0 is not valid */
2200 packets
[i
]->dp_hash
= hash
;
2205 case OVS_ACTION_ATTR_RECIRC
:
2206 if (*depth
< MAX_RECIRC_DEPTH
) {
2209 for (i
= 0; i
< cnt
; i
++) {
2210 struct dpif_packet
*recirc_pkt
;
2211 struct pkt_metadata recirc_md
= *md
;
2213 recirc_pkt
= (may_steal
) ? packets
[i
]
2214 : dpif_packet_clone(packets
[i
]);
2216 recirc_md
.recirc_id
= nl_attr_get_u32(a
);
2218 /* Hash is private to each packet */
2219 recirc_md
.dp_hash
= packets
[i
]->dp_hash
;
2221 dp_netdev_input(dp
, &recirc_pkt
, 1, &recirc_md
);
2227 VLOG_WARN("Packet dropped. Max recirculation depth exceeded.");
2229 for (i
= 0; i
< cnt
; i
++) {
2230 dpif_packet_delete(packets
[i
]);
2236 case OVS_ACTION_ATTR_PUSH_VLAN
:
2237 case OVS_ACTION_ATTR_POP_VLAN
:
2238 case OVS_ACTION_ATTR_PUSH_MPLS
:
2239 case OVS_ACTION_ATTR_POP_MPLS
:
2240 case OVS_ACTION_ATTR_SET
:
2241 case OVS_ACTION_ATTR_SAMPLE
:
2242 case OVS_ACTION_ATTR_UNSPEC
:
2243 case __OVS_ACTION_ATTR_MAX
:
2249 dp_netdev_execute_actions(struct dp_netdev
*dp
,
2250 struct dpif_packet
**packets
, int cnt
,
2251 bool may_steal
, struct pkt_metadata
*md
,
2252 const struct nlattr
*actions
, size_t actions_len
)
2254 struct dp_netdev_execute_aux aux
= {dp
};
2256 odp_execute_actions(&aux
, packets
, cnt
, may_steal
, md
, actions
,
2257 actions_len
, dp_execute_cb
);
2260 const struct dpif_class dpif_netdev_class
= {
2262 dpif_netdev_enumerate
,
2263 dpif_netdev_port_open_type
,
2266 dpif_netdev_destroy
,
2269 dpif_netdev_get_stats
,
2270 dpif_netdev_port_add
,
2271 dpif_netdev_port_del
,
2272 dpif_netdev_port_query_by_number
,
2273 dpif_netdev_port_query_by_name
,
2274 NULL
, /* port_get_pid */
2275 dpif_netdev_port_dump_start
,
2276 dpif_netdev_port_dump_next
,
2277 dpif_netdev_port_dump_done
,
2278 dpif_netdev_port_poll
,
2279 dpif_netdev_port_poll_wait
,
2280 dpif_netdev_flow_flush
,
2281 dpif_netdev_flow_dump_create
,
2282 dpif_netdev_flow_dump_destroy
,
2283 dpif_netdev_flow_dump_thread_create
,
2284 dpif_netdev_flow_dump_thread_destroy
,
2285 dpif_netdev_flow_dump_next
,
2286 dpif_netdev_operate
,
2287 NULL
, /* recv_set */
2288 NULL
, /* handlers_set */
2289 dpif_netdev_queue_to_priority
,
2291 NULL
, /* recv_wait */
2292 NULL
, /* recv_purge */
2293 dpif_netdev_register_upcall_cb
,
2294 dpif_netdev_enable_upcall
,
2295 dpif_netdev_disable_upcall
,
2299 dpif_dummy_change_port_number(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
2300 const char *argv
[], void *aux OVS_UNUSED
)
2302 struct dp_netdev_port
*old_port
;
2303 struct dp_netdev_port
*new_port
;
2304 struct dp_netdev
*dp
;
2307 ovs_mutex_lock(&dp_netdev_mutex
);
2308 dp
= shash_find_data(&dp_netdevs
, argv
[1]);
2309 if (!dp
|| !dpif_netdev_class_is_dummy(dp
->class)) {
2310 ovs_mutex_unlock(&dp_netdev_mutex
);
2311 unixctl_command_reply_error(conn
, "unknown datapath or not a dummy");
2314 ovs_refcount_ref(&dp
->ref_cnt
);
2315 ovs_mutex_unlock(&dp_netdev_mutex
);
2317 ovs_mutex_lock(&dp
->port_mutex
);
2318 if (get_port_by_name(dp
, argv
[2], &old_port
)) {
2319 unixctl_command_reply_error(conn
, "unknown port");
2323 port_no
= u32_to_odp(atoi(argv
[3]));
2324 if (!port_no
|| port_no
== ODPP_NONE
) {
2325 unixctl_command_reply_error(conn
, "bad port number");
2328 if (dp_netdev_lookup_port(dp
, port_no
)) {
2329 unixctl_command_reply_error(conn
, "port number already in use");
2333 /* Remove old port. */
2334 cmap_remove(&dp
->ports
, &old_port
->node
, hash_port_no(old_port
->port_no
));
2335 ovsrcu_postpone(free
, old_port
);
2337 /* Insert new port (cmap semantics mean we cannot re-insert 'old_port'). */
2338 new_port
= xmemdup(old_port
, sizeof *old_port
);
2339 new_port
->port_no
= port_no
;
2340 cmap_insert(&dp
->ports
, &new_port
->node
, hash_port_no(port_no
));
2342 seq_change(dp
->port_seq
);
2343 unixctl_command_reply(conn
, NULL
);
2346 ovs_mutex_unlock(&dp
->port_mutex
);
2347 dp_netdev_unref(dp
);
2351 dpif_dummy_delete_port(struct unixctl_conn
*conn
, int argc OVS_UNUSED
,
2352 const char *argv
[], void *aux OVS_UNUSED
)
2354 struct dp_netdev_port
*port
;
2355 struct dp_netdev
*dp
;
2357 ovs_mutex_lock(&dp_netdev_mutex
);
2358 dp
= shash_find_data(&dp_netdevs
, argv
[1]);
2359 if (!dp
|| !dpif_netdev_class_is_dummy(dp
->class)) {
2360 ovs_mutex_unlock(&dp_netdev_mutex
);
2361 unixctl_command_reply_error(conn
, "unknown datapath or not a dummy");
2364 ovs_refcount_ref(&dp
->ref_cnt
);
2365 ovs_mutex_unlock(&dp_netdev_mutex
);
2367 ovs_mutex_lock(&dp
->port_mutex
);
2368 if (get_port_by_name(dp
, argv
[2], &port
)) {
2369 unixctl_command_reply_error(conn
, "unknown port");
2370 } else if (port
->port_no
== ODPP_LOCAL
) {
2371 unixctl_command_reply_error(conn
, "can't delete local port");
2373 do_del_port(dp
, port
);
2374 unixctl_command_reply(conn
, NULL
);
2376 ovs_mutex_unlock(&dp
->port_mutex
);
2378 dp_netdev_unref(dp
);
2382 dpif_dummy_register__(const char *type
)
2384 struct dpif_class
*class;
2386 class = xmalloc(sizeof *class);
2387 *class = dpif_netdev_class
;
2388 class->type
= xstrdup(type
);
2389 dp_register_provider(class);
2393 dpif_dummy_register(bool override
)
2400 dp_enumerate_types(&types
);
2401 SSET_FOR_EACH (type
, &types
) {
2402 if (!dp_unregister_provider(type
)) {
2403 dpif_dummy_register__(type
);
2406 sset_destroy(&types
);
2409 dpif_dummy_register__("dummy");
2411 unixctl_command_register("dpif-dummy/change-port-number",
2412 "DP PORT NEW-NUMBER",
2413 3, 3, dpif_dummy_change_port_number
, NULL
);
2414 unixctl_command_register("dpif-dummy/delete-port", "DP PORT",
2415 2, 2, dpif_dummy_delete_port
, NULL
);