2 * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
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.
19 #include "dpif-linux.h"
27 #include <linux/types.h>
28 #include <linux/pkt_sched.h>
29 #include <linux/rtnetlink.h>
30 #include <linux/sockios.h>
35 #include "dpif-provider.h"
37 #include "netdev-vport.h"
38 #include "netlink-socket.h"
42 #include "openvswitch/tunnel.h"
44 #include "poll-loop.h"
45 #include "rtnetlink.h"
46 #include "rtnetlink-link.h"
49 #include "unaligned.h"
53 VLOG_DEFINE_THIS_MODULE(dpif_linux
);
55 struct dpif_linux_dp
{
56 /* Generic Netlink header. */
59 /* struct odp_header. */
63 const char *name
; /* ODP_DP_ATTR_NAME. */
64 struct odp_stats stats
; /* ODP_DP_ATTR_STATS. */
65 enum odp_frag_handling ipv4_frags
; /* ODP_DP_ATTR_IPV4_FRAGS. */
66 const uint32_t *sampling
; /* ODP_DP_ATTR_SAMPLING. */
67 uint32_t mcgroups
[DPIF_N_UC_TYPES
]; /* ODP_DP_ATTR_MCGROUPS. */
70 static void dpif_linux_dp_init(struct dpif_linux_dp
*);
71 static int dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp
*,
72 const struct ofpbuf
*);
73 static void dpif_linux_dp_dump_start(struct nl_dump
*);
74 static int dpif_linux_dp_transact(const struct dpif_linux_dp
*request
,
75 struct dpif_linux_dp
*reply
,
76 struct ofpbuf
**bufp
);
77 static int dpif_linux_dp_get(const struct dpif
*, struct dpif_linux_dp
*reply
,
78 struct ofpbuf
**bufp
);
80 struct dpif_linux_flow
{
81 /* Generic Netlink header. */
84 /* struct odp_header. */
85 unsigned int nlmsg_flags
;
90 * The 'stats' and 'used' members point to 64-bit data that might only be
91 * aligned on 32-bit boundaries, so get_unaligned_u64() should be used to
92 * access their values. */
93 const struct nlattr
*key
; /* ODP_FLOW_ATTR_KEY. */
95 const struct nlattr
*actions
; /* ODP_FLOW_ATTR_ACTIONS. */
97 const struct odp_flow_stats
*stats
; /* ODP_FLOW_ATTR_STATS. */
98 const uint8_t *tcp_flags
; /* ODP_FLOW_ATTR_TCP_FLAGS. */
99 const uint64_t *used
; /* ODP_FLOW_ATTR_USED. */
100 bool clear
; /* ODP_FLOW_ATTR_CLEAR. */
103 static void dpif_linux_flow_init(struct dpif_linux_flow
*);
104 static int dpif_linux_flow_from_ofpbuf(struct dpif_linux_flow
*,
105 const struct ofpbuf
*);
106 static void dpif_linux_flow_to_ofpbuf(const struct dpif_linux_flow
*,
108 static int dpif_linux_flow_transact(const struct dpif_linux_flow
*request
,
109 struct dpif_linux_flow
*reply
,
110 struct ofpbuf
**bufp
);
111 static void dpif_linux_flow_get_stats(const struct dpif_linux_flow
*,
112 struct dpif_flow_stats
*);
114 /* Datapath interface for the openvswitch Linux kernel module. */
119 /* Multicast group messages. */
120 struct nl_sock
*mc_sock
;
121 uint32_t mcgroups
[DPIF_N_UC_TYPES
];
122 unsigned int listen_mask
;
124 /* Change notification. */
125 struct shash changed_ports
; /* Ports that have changed. */
126 struct rtnetlink_notifier port_notifier
;
130 static struct vlog_rate_limit error_rl
= VLOG_RATE_LIMIT_INIT(9999, 5);
132 /* Generic Netlink family numbers for ODP. */
133 static int odp_datapath_family
;
134 static int odp_vport_family
;
135 static int odp_flow_family
;
136 static int odp_packet_family
;
138 /* Generic Netlink socket. */
139 static struct nl_sock
*genl_sock
;
141 static int dpif_linux_init(void);
142 static int open_dpif(const struct dpif_linux_dp
*, struct dpif
**);
143 static void dpif_linux_port_changed(const struct rtnetlink_link_change
*,
146 static void dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport
*,
148 static int dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport
*,
149 const struct ofpbuf
*);
151 static struct dpif_linux
*
152 dpif_linux_cast(const struct dpif
*dpif
)
154 dpif_assert_class(dpif
, &dpif_linux_class
);
155 return CONTAINER_OF(dpif
, struct dpif_linux
, dpif
);
159 dpif_linux_enumerate(struct svec
*all_dps
)
165 error
= dpif_linux_init();
170 dpif_linux_dp_dump_start(&dump
);
171 while (nl_dump_next(&dump
, &msg
)) {
172 struct dpif_linux_dp dp
;
174 if (!dpif_linux_dp_from_ofpbuf(&dp
, &msg
)) {
175 svec_add(all_dps
, dp
.name
);
178 return nl_dump_done(&dump
);
182 dpif_linux_open(const struct dpif_class
*class OVS_UNUSED
, const char *name
,
183 bool create
, struct dpif
**dpifp
)
185 struct dpif_linux_dp dp_request
, dp
;
189 error
= dpif_linux_init();
194 /* Create or look up datapath. */
195 dpif_linux_dp_init(&dp_request
);
196 dp_request
.cmd
= create
? ODP_DP_CMD_NEW
: ODP_DP_CMD_GET
;
197 dp_request
.name
= name
;
198 error
= dpif_linux_dp_transact(&dp_request
, &dp
, &buf
);
202 error
= open_dpif(&dp
, dpifp
);
209 open_dpif(const struct dpif_linux_dp
*dp
, struct dpif
**dpifp
)
211 struct dpif_linux
*dpif
;
215 dpif
= xmalloc(sizeof *dpif
);
216 error
= rtnetlink_link_notifier_register(&dpif
->port_notifier
,
217 dpif_linux_port_changed
, dpif
);
222 dpif_init(&dpif
->dpif
, &dpif_linux_class
, dp
->name
,
223 dp
->dp_ifindex
, dp
->dp_ifindex
);
225 dpif
->mc_sock
= NULL
;
226 for (i
= 0; i
< DPIF_N_UC_TYPES
; i
++) {
227 dpif
->mcgroups
[i
] = dp
->mcgroups
[i
];
229 dpif
->listen_mask
= 0;
230 dpif
->dp_ifindex
= dp
->dp_ifindex
;
231 shash_init(&dpif
->changed_ports
);
232 dpif
->change_error
= false;
233 *dpifp
= &dpif
->dpif
;
243 dpif_linux_close(struct dpif
*dpif_
)
245 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
246 rtnetlink_link_notifier_unregister(&dpif
->port_notifier
);
247 shash_destroy(&dpif
->changed_ports
);
252 dpif_linux_destroy(struct dpif
*dpif_
)
254 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
255 struct dpif_linux_dp dp
;
257 dpif_linux_dp_init(&dp
);
258 dp
.cmd
= ODP_DP_CMD_DEL
;
259 dp
.dp_ifindex
= dpif
->dp_ifindex
;
260 return dpif_linux_dp_transact(&dp
, NULL
, NULL
);
264 dpif_linux_get_stats(const struct dpif
*dpif_
, struct odp_stats
*stats
)
266 struct dpif_linux_dp dp
;
270 error
= dpif_linux_dp_get(dpif_
, &dp
, &buf
);
279 dpif_linux_get_drop_frags(const struct dpif
*dpif_
, bool *drop_fragsp
)
281 struct dpif_linux_dp dp
;
285 error
= dpif_linux_dp_get(dpif_
, &dp
, &buf
);
287 *drop_fragsp
= dp
.ipv4_frags
== ODP_DP_FRAG_DROP
;
294 dpif_linux_set_drop_frags(struct dpif
*dpif_
, bool drop_frags
)
296 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
297 struct dpif_linux_dp dp
;
299 dpif_linux_dp_init(&dp
);
300 dp
.cmd
= ODP_DP_CMD_SET
;
301 dp
.dp_ifindex
= dpif
->dp_ifindex
;
302 dp
.ipv4_frags
= drop_frags
? ODP_DP_FRAG_DROP
: ODP_DP_FRAG_ZERO
;
303 return dpif_linux_dp_transact(&dp
, NULL
, NULL
);
307 dpif_linux_port_add(struct dpif
*dpif_
, struct netdev
*netdev
,
310 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
311 const char *name
= netdev_get_name(netdev
);
312 const char *type
= netdev_get_type(netdev
);
313 struct dpif_linux_vport request
, reply
;
314 const struct ofpbuf
*options
;
318 dpif_linux_vport_init(&request
);
319 request
.cmd
= ODP_VPORT_CMD_NEW
;
320 request
.dp_ifindex
= dpif
->dp_ifindex
;
321 request
.type
= netdev_vport_get_vport_type(netdev
);
322 if (request
.type
== ODP_VPORT_TYPE_UNSPEC
) {
323 VLOG_WARN_RL(&error_rl
, "%s: cannot create port `%s' because it has "
324 "unsupported type `%s'",
325 dpif_name(dpif_
), name
, type
);
330 options
= netdev_vport_get_options(netdev
);
331 if (options
&& options
->size
) {
332 request
.options
= options
->data
;
333 request
.options_len
= options
->size
;
336 error
= dpif_linux_vport_transact(&request
, &reply
, &buf
);
338 *port_nop
= reply
.port_no
;
346 dpif_linux_port_del(struct dpif
*dpif_
, uint16_t port_no
)
348 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
349 struct dpif_linux_vport vport
;
351 dpif_linux_vport_init(&vport
);
352 vport
.cmd
= ODP_VPORT_CMD_DEL
;
353 vport
.dp_ifindex
= dpif
->dp_ifindex
;
354 vport
.port_no
= port_no
;
355 return dpif_linux_vport_transact(&vport
, NULL
, NULL
);
359 dpif_linux_port_query__(const struct dpif
*dpif
, uint32_t port_no
,
360 const char *port_name
, struct dpif_port
*dpif_port
)
362 struct dpif_linux_vport request
;
363 struct dpif_linux_vport reply
;
367 dpif_linux_vport_init(&request
);
368 request
.cmd
= ODP_VPORT_CMD_GET
;
369 request
.dp_ifindex
= dpif_linux_cast(dpif
)->dp_ifindex
;
370 request
.port_no
= port_no
;
371 request
.name
= port_name
;
373 error
= dpif_linux_vport_transact(&request
, &reply
, &buf
);
375 dpif_port
->name
= xstrdup(reply
.name
);
376 dpif_port
->type
= xstrdup(netdev_vport_get_netdev_type(&reply
));
377 dpif_port
->port_no
= reply
.port_no
;
384 dpif_linux_port_query_by_number(const struct dpif
*dpif
, uint16_t port_no
,
385 struct dpif_port
*dpif_port
)
387 return dpif_linux_port_query__(dpif
, port_no
, NULL
, dpif_port
);
391 dpif_linux_port_query_by_name(const struct dpif
*dpif
, const char *devname
,
392 struct dpif_port
*dpif_port
)
394 return dpif_linux_port_query__(dpif
, 0, devname
, dpif_port
);
398 dpif_linux_get_max_ports(const struct dpif
*dpif OVS_UNUSED
)
400 /* If the datapath increases its range of supported ports, then it should
401 * start reporting that. */
406 dpif_linux_flow_flush(struct dpif
*dpif_
)
408 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
409 struct dpif_linux_flow flow
;
411 dpif_linux_flow_init(&flow
);
412 flow
.cmd
= ODP_FLOW_CMD_DEL
;
413 flow
.dp_ifindex
= dpif
->dp_ifindex
;
414 return dpif_linux_flow_transact(&flow
, NULL
, NULL
);
417 struct dpif_linux_port_state
{
422 dpif_linux_port_dump_start(const struct dpif
*dpif_
, void **statep
)
424 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
425 struct dpif_linux_port_state
*state
;
426 struct dpif_linux_vport request
;
429 *statep
= state
= xmalloc(sizeof *state
);
431 dpif_linux_vport_init(&request
);
432 request
.cmd
= ODP_DP_CMD_GET
;
433 request
.dp_ifindex
= dpif
->dp_ifindex
;
435 buf
= ofpbuf_new(1024);
436 dpif_linux_vport_to_ofpbuf(&request
, buf
);
437 nl_dump_start(&state
->dump
, genl_sock
, buf
);
444 dpif_linux_port_dump_next(const struct dpif
*dpif OVS_UNUSED
, void *state_
,
445 struct dpif_port
*dpif_port
)
447 struct dpif_linux_port_state
*state
= state_
;
448 struct dpif_linux_vport vport
;
452 if (!nl_dump_next(&state
->dump
, &buf
)) {
456 error
= dpif_linux_vport_from_ofpbuf(&vport
, &buf
);
461 dpif_port
->name
= (char *) vport
.name
;
462 dpif_port
->type
= (char *) netdev_vport_get_netdev_type(&vport
);
463 dpif_port
->port_no
= vport
.port_no
;
468 dpif_linux_port_dump_done(const struct dpif
*dpif OVS_UNUSED
, void *state_
)
470 struct dpif_linux_port_state
*state
= state_
;
471 int error
= nl_dump_done(&state
->dump
);
477 dpif_linux_port_poll(const struct dpif
*dpif_
, char **devnamep
)
479 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
481 if (dpif
->change_error
) {
482 dpif
->change_error
= false;
483 shash_clear(&dpif
->changed_ports
);
485 } else if (!shash_is_empty(&dpif
->changed_ports
)) {
486 struct shash_node
*node
= shash_first(&dpif
->changed_ports
);
487 *devnamep
= shash_steal(&dpif
->changed_ports
, node
);
495 dpif_linux_port_poll_wait(const struct dpif
*dpif_
)
497 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
498 if (!shash_is_empty(&dpif
->changed_ports
) || dpif
->change_error
) {
499 poll_immediate_wake();
501 rtnetlink_link_notifier_wait();
506 dpif_linux_flow_get(const struct dpif
*dpif_
,
507 const struct nlattr
*key
, size_t key_len
,
508 struct ofpbuf
**actionsp
, struct dpif_flow_stats
*stats
)
510 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
511 struct dpif_linux_flow request
, reply
;
515 dpif_linux_flow_init(&request
);
516 request
.cmd
= ODP_FLOW_CMD_GET
;
517 request
.dp_ifindex
= dpif
->dp_ifindex
;
519 request
.key_len
= key_len
;
520 error
= dpif_linux_flow_transact(&request
, &reply
, &buf
);
523 dpif_linux_flow_get_stats(&reply
, stats
);
526 buf
->data
= (void *) reply
.actions
;
527 buf
->size
= reply
.actions_len
;
537 dpif_linux_flow_put(struct dpif
*dpif_
, enum dpif_flow_put_flags flags
,
538 const struct nlattr
*key
, size_t key_len
,
539 const struct nlattr
*actions
, size_t actions_len
,
540 struct dpif_flow_stats
*stats
)
542 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
543 struct dpif_linux_flow request
, reply
;
547 dpif_linux_flow_init(&request
);
548 request
.cmd
= flags
& DPIF_FP_CREATE
? ODP_FLOW_CMD_NEW
: ODP_FLOW_CMD_SET
;
549 request
.dp_ifindex
= dpif
->dp_ifindex
;
551 request
.key_len
= key_len
;
552 request
.actions
= actions
;
553 request
.actions_len
= actions_len
;
554 if (flags
& DPIF_FP_ZERO_STATS
) {
555 request
.clear
= true;
557 request
.nlmsg_flags
= flags
& DPIF_FP_MODIFY
? 0 : NLM_F_CREATE
;
558 error
= dpif_linux_flow_transact(&request
,
559 stats
? &reply
: NULL
,
560 stats
? &buf
: NULL
);
561 if (!error
&& stats
) {
562 dpif_linux_flow_get_stats(&reply
, stats
);
569 dpif_linux_flow_del(struct dpif
*dpif_
,
570 const struct nlattr
*key
, size_t key_len
,
571 struct dpif_flow_stats
*stats
)
573 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
574 struct dpif_linux_flow request
, reply
;
578 dpif_linux_flow_init(&request
);
579 request
.cmd
= ODP_FLOW_CMD_DEL
;
580 request
.dp_ifindex
= dpif
->dp_ifindex
;
582 request
.key_len
= key_len
;
583 error
= dpif_linux_flow_transact(&request
,
584 stats
? &reply
: NULL
,
585 stats
? &buf
: NULL
);
586 if (!error
&& stats
) {
587 dpif_linux_flow_get_stats(&reply
, stats
);
593 struct dpif_linux_flow_state
{
595 struct dpif_linux_flow flow
;
596 struct dpif_flow_stats stats
;
600 dpif_linux_flow_dump_start(const struct dpif
*dpif_
, void **statep
)
602 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
603 struct dpif_linux_flow_state
*state
;
604 struct dpif_linux_flow request
;
607 *statep
= state
= xmalloc(sizeof *state
);
609 dpif_linux_flow_init(&request
);
610 request
.cmd
= ODP_DP_CMD_GET
;
611 request
.dp_ifindex
= dpif
->dp_ifindex
;
613 buf
= ofpbuf_new(1024);
614 dpif_linux_flow_to_ofpbuf(&request
, buf
);
615 nl_dump_start(&state
->dump
, genl_sock
, buf
);
622 dpif_linux_flow_dump_next(const struct dpif
*dpif_ OVS_UNUSED
, void *state_
,
623 const struct nlattr
**key
, size_t *key_len
,
624 const struct nlattr
**actions
, size_t *actions_len
,
625 const struct dpif_flow_stats
**stats
)
627 struct dpif_linux_flow_state
*state
= state_
;
631 if (!nl_dump_next(&state
->dump
, &buf
)) {
635 error
= dpif_linux_flow_from_ofpbuf(&state
->flow
, &buf
);
638 *key
= state
->flow
.key
;
639 *key_len
= state
->flow
.key_len
;
642 *actions
= state
->flow
.actions
;
643 *actions_len
= state
->flow
.actions_len
;
646 dpif_linux_flow_get_stats(&state
->flow
, &state
->stats
);
647 *stats
= &state
->stats
;
654 dpif_linux_flow_dump_done(const struct dpif
*dpif OVS_UNUSED
, void *state_
)
656 struct dpif_linux_flow_state
*state
= state_
;
657 int error
= nl_dump_done(&state
->dump
);
663 dpif_linux_execute(struct dpif
*dpif_
,
664 const struct nlattr
*actions
, size_t actions_len
,
665 const struct ofpbuf
*packet
)
667 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
668 struct odp_header
*execute
;
672 buf
= ofpbuf_new(128 + actions_len
+ packet
->size
);
674 nl_msg_put_genlmsghdr(buf
, 0, odp_packet_family
, NLM_F_REQUEST
,
675 ODP_PACKET_CMD_EXECUTE
, 1);
677 execute
= ofpbuf_put_uninit(buf
, sizeof *execute
);
678 execute
->dp_ifindex
= dpif
->dp_ifindex
;
680 nl_msg_put_unspec(buf
, ODP_PACKET_ATTR_PACKET
, packet
->data
, packet
->size
);
681 nl_msg_put_unspec(buf
, ODP_PACKET_ATTR_ACTIONS
, actions
, actions_len
);
683 error
= nl_sock_transact(genl_sock
, buf
, NULL
);
689 dpif_linux_recv_get_mask(const struct dpif
*dpif_
, int *listen_mask
)
691 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
692 *listen_mask
= dpif
->listen_mask
;
697 dpif_linux_recv_set_mask(struct dpif
*dpif_
, int listen_mask
)
699 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
703 if (listen_mask
== dpif
->listen_mask
) {
705 } else if (!listen_mask
) {
706 nl_sock_destroy(dpif
->mc_sock
);
707 dpif
->mc_sock
= NULL
;
708 dpif
->listen_mask
= 0;
710 } else if (!dpif
->mc_sock
) {
711 error
= nl_sock_create(NETLINK_GENERIC
, &dpif
->mc_sock
);
717 /* Unsubscribe from old groups. */
718 for (i
= 0; i
< DPIF_N_UC_TYPES
; i
++) {
719 if (dpif
->listen_mask
& (1u << i
)) {
720 nl_sock_leave_mcgroup(dpif
->mc_sock
, dpif
->mcgroups
[i
]);
724 /* Update listen_mask. */
725 dpif
->listen_mask
= listen_mask
;
727 /* Subscribe to new groups. */
729 for (i
= 0; i
< DPIF_N_UC_TYPES
; i
++) {
730 if (dpif
->listen_mask
& (1u << i
)) {
733 retval
= nl_sock_join_mcgroup(dpif
->mc_sock
, dpif
->mcgroups
[i
]);
743 dpif_linux_get_sflow_probability(const struct dpif
*dpif_
,
744 uint32_t *probability
)
746 struct dpif_linux_dp dp
;
750 error
= dpif_linux_dp_get(dpif_
, &dp
, &buf
);
752 *probability
= dp
.sampling
? *dp
.sampling
: 0;
759 dpif_linux_set_sflow_probability(struct dpif
*dpif_
, uint32_t probability
)
761 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
762 struct dpif_linux_dp dp
;
764 dpif_linux_dp_init(&dp
);
765 dp
.cmd
= ODP_DP_CMD_SET
;
766 dp
.dp_ifindex
= dpif
->dp_ifindex
;
767 dp
.sampling
= &probability
;
768 return dpif_linux_dp_transact(&dp
, NULL
, NULL
);
772 dpif_linux_queue_to_priority(const struct dpif
*dpif OVS_UNUSED
,
773 uint32_t queue_id
, uint32_t *priority
)
775 if (queue_id
< 0xf000) {
776 *priority
= TC_H_MAKE(1 << 16, queue_id
+ 1);
784 parse_odp_packet(struct ofpbuf
*buf
, struct dpif_upcall
*upcall
,
787 static const struct nl_policy odp_packet_policy
[] = {
788 /* Always present. */
789 [ODP_PACKET_ATTR_PACKET
] = { .type
= NL_A_UNSPEC
,
790 .min_len
= ETH_HEADER_LEN
},
791 [ODP_PACKET_ATTR_KEY
] = { .type
= NL_A_NESTED
},
793 /* ODP_PACKET_CMD_ACTION only. */
794 [ODP_PACKET_ATTR_USERDATA
] = { .type
= NL_A_U64
, .optional
= true },
796 /* ODP_PACKET_CMD_SAMPLE only. */
797 [ODP_PACKET_ATTR_SAMPLE_POOL
] = { .type
= NL_A_U32
, .optional
= true },
798 [ODP_PACKET_ATTR_ACTIONS
] = { .type
= NL_A_NESTED
, .optional
= true },
801 struct odp_header
*odp_header
;
802 struct nlattr
*a
[ARRAY_SIZE(odp_packet_policy
)];
803 struct nlmsghdr
*nlmsg
;
804 struct genlmsghdr
*genl
;
808 ofpbuf_use_const(&b
, buf
->data
, buf
->size
);
810 nlmsg
= ofpbuf_try_pull(&b
, sizeof *nlmsg
);
811 genl
= ofpbuf_try_pull(&b
, sizeof *genl
);
812 odp_header
= ofpbuf_try_pull(&b
, sizeof *odp_header
);
813 if (!nlmsg
|| !genl
|| !odp_header
814 || nlmsg
->nlmsg_type
!= odp_packet_family
815 || !nl_policy_parse(&b
, 0, odp_packet_policy
, a
,
816 ARRAY_SIZE(odp_packet_policy
))) {
820 type
= (genl
->cmd
== ODP_PACKET_CMD_MISS
? DPIF_UC_MISS
821 : genl
->cmd
== ODP_PACKET_CMD_ACTION
? DPIF_UC_ACTION
822 : genl
->cmd
== ODP_PACKET_CMD_SAMPLE
? DPIF_UC_SAMPLE
828 memset(upcall
, 0, sizeof *upcall
);
830 upcall
->packet
= buf
;
831 upcall
->packet
->data
= (void *) nl_attr_get(a
[ODP_PACKET_ATTR_PACKET
]);
832 upcall
->packet
->size
= nl_attr_get_size(a
[ODP_PACKET_ATTR_PACKET
]);
833 upcall
->key
= (void *) nl_attr_get(a
[ODP_PACKET_ATTR_KEY
]);
834 upcall
->key_len
= nl_attr_get_size(a
[ODP_PACKET_ATTR_KEY
]);
835 upcall
->userdata
= (a
[ODP_PACKET_ATTR_USERDATA
]
836 ? nl_attr_get_u64(a
[ODP_PACKET_ATTR_USERDATA
])
838 upcall
->sample_pool
= (a
[ODP_PACKET_ATTR_SAMPLE_POOL
]
839 ? nl_attr_get_u32(a
[ODP_PACKET_ATTR_SAMPLE_POOL
])
841 if (a
[ODP_PACKET_ATTR_ACTIONS
]) {
842 upcall
->actions
= (void *) nl_attr_get(a
[ODP_PACKET_ATTR_ACTIONS
]);
843 upcall
->actions_len
= nl_attr_get_size(a
[ODP_PACKET_ATTR_ACTIONS
]);
846 *dp_ifindex
= odp_header
->dp_ifindex
;
852 dpif_linux_recv(struct dpif
*dpif_
, struct dpif_upcall
*upcall
)
854 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
859 if (!dpif
->mc_sock
) {
863 for (i
= 0; i
< 50; i
++) {
866 error
= nl_sock_recv(dpif
->mc_sock
, &buf
, false);
871 error
= parse_odp_packet(buf
, upcall
, &dp_ifindex
);
873 && dp_ifindex
== dpif
->dp_ifindex
874 && dpif
->listen_mask
& (1u << upcall
->type
)) {
888 dpif_linux_recv_wait(struct dpif
*dpif_
)
890 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
892 nl_sock_wait(dpif
->mc_sock
, POLLIN
);
897 dpif_linux_recv_purge(struct dpif
*dpif_
)
899 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
902 nl_sock_drain(dpif
->mc_sock
);
906 const struct dpif_class dpif_linux_class
= {
910 dpif_linux_enumerate
,
914 dpif_linux_get_stats
,
915 dpif_linux_get_drop_frags
,
916 dpif_linux_set_drop_frags
,
919 dpif_linux_port_query_by_number
,
920 dpif_linux_port_query_by_name
,
921 dpif_linux_get_max_ports
,
922 dpif_linux_port_dump_start
,
923 dpif_linux_port_dump_next
,
924 dpif_linux_port_dump_done
,
925 dpif_linux_port_poll
,
926 dpif_linux_port_poll_wait
,
930 dpif_linux_flow_flush
,
931 dpif_linux_flow_dump_start
,
932 dpif_linux_flow_dump_next
,
933 dpif_linux_flow_dump_done
,
935 dpif_linux_recv_get_mask
,
936 dpif_linux_recv_set_mask
,
937 dpif_linux_get_sflow_probability
,
938 dpif_linux_set_sflow_probability
,
939 dpif_linux_queue_to_priority
,
941 dpif_linux_recv_wait
,
942 dpif_linux_recv_purge
,
946 dpif_linux_init(void)
948 static int error
= -1;
951 error
= nl_lookup_genl_family(ODP_DATAPATH_FAMILY
,
952 &odp_datapath_family
);
954 VLOG_ERR("Generic Netlink family '%s' does not exist. "
955 "The Open vSwitch kernel module is probably not loaded.",
956 ODP_DATAPATH_FAMILY
);
959 error
= nl_lookup_genl_family(ODP_VPORT_FAMILY
, &odp_vport_family
);
962 error
= nl_lookup_genl_family(ODP_FLOW_FAMILY
, &odp_flow_family
);
965 error
= nl_lookup_genl_family(ODP_PACKET_FAMILY
,
969 error
= nl_sock_create(NETLINK_GENERIC
, &genl_sock
);
977 dpif_linux_is_internal_device(const char *name
)
979 struct dpif_linux_vport reply
;
983 error
= dpif_linux_vport_get(name
, &reply
, &buf
);
986 } else if (error
!= ENODEV
) {
987 VLOG_WARN_RL(&error_rl
, "%s: vport query failed (%s)",
988 name
, strerror(error
));
991 return reply
.type
== ODP_VPORT_TYPE_INTERNAL
;
995 dpif_linux_port_changed(const struct rtnetlink_link_change
*change
,
998 struct dpif_linux
*dpif
= dpif_
;
1001 if (change
->master_ifindex
== dpif
->dp_ifindex
1002 && (change
->nlmsg_type
== RTM_NEWLINK
1003 || change
->nlmsg_type
== RTM_DELLINK
))
1005 /* Our datapath changed, either adding a new port or deleting an
1007 shash_add_once(&dpif
->changed_ports
, change
->ifname
, NULL
);
1010 dpif
->change_error
= true;
1014 /* Parses the contents of 'buf', which contains a "struct odp_header" followed
1015 * by Netlink attributes, into 'vport'. Returns 0 if successful, otherwise a
1016 * positive errno value.
1018 * 'vport' will contain pointers into 'buf', so the caller should not free
1019 * 'buf' while 'vport' is still in use. */
1021 dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport
*vport
,
1022 const struct ofpbuf
*buf
)
1024 static const struct nl_policy odp_vport_policy
[] = {
1025 [ODP_VPORT_ATTR_PORT_NO
] = { .type
= NL_A_U32
},
1026 [ODP_VPORT_ATTR_TYPE
] = { .type
= NL_A_U32
},
1027 [ODP_VPORT_ATTR_NAME
] = { .type
= NL_A_STRING
, .max_len
= IFNAMSIZ
},
1028 [ODP_VPORT_ATTR_STATS
] = { .type
= NL_A_UNSPEC
,
1029 .min_len
= sizeof(struct rtnl_link_stats64
),
1030 .max_len
= sizeof(struct rtnl_link_stats64
),
1032 [ODP_VPORT_ATTR_ADDRESS
] = { .type
= NL_A_UNSPEC
,
1033 .min_len
= ETH_ADDR_LEN
,
1034 .max_len
= ETH_ADDR_LEN
,
1036 [ODP_VPORT_ATTR_MTU
] = { .type
= NL_A_U32
, .optional
= true },
1037 [ODP_VPORT_ATTR_OPTIONS
] = { .type
= NL_A_NESTED
, .optional
= true },
1038 [ODP_VPORT_ATTR_IFINDEX
] = { .type
= NL_A_U32
, .optional
= true },
1039 [ODP_VPORT_ATTR_IFLINK
] = { .type
= NL_A_U32
, .optional
= true },
1042 struct nlattr
*a
[ARRAY_SIZE(odp_vport_policy
)];
1043 struct odp_header
*odp_header
;
1044 struct nlmsghdr
*nlmsg
;
1045 struct genlmsghdr
*genl
;
1048 dpif_linux_vport_init(vport
);
1050 ofpbuf_use_const(&b
, buf
->data
, buf
->size
);
1051 nlmsg
= ofpbuf_try_pull(&b
, sizeof *nlmsg
);
1052 genl
= ofpbuf_try_pull(&b
, sizeof *genl
);
1053 odp_header
= ofpbuf_try_pull(&b
, sizeof *odp_header
);
1054 if (!nlmsg
|| !genl
|| !odp_header
1055 || nlmsg
->nlmsg_type
!= odp_vport_family
1056 || !nl_policy_parse(&b
, 0, odp_vport_policy
, a
,
1057 ARRAY_SIZE(odp_vport_policy
))) {
1061 vport
->cmd
= genl
->cmd
;
1062 vport
->dp_ifindex
= odp_header
->dp_ifindex
;
1063 vport
->port_no
= nl_attr_get_u32(a
[ODP_VPORT_ATTR_PORT_NO
]);
1064 vport
->type
= nl_attr_get_u32(a
[ODP_VPORT_ATTR_TYPE
]);
1065 vport
->name
= nl_attr_get_string(a
[ODP_VPORT_ATTR_NAME
]);
1066 if (a
[ODP_VPORT_ATTR_STATS
]) {
1067 vport
->stats
= nl_attr_get(a
[ODP_VPORT_ATTR_STATS
]);
1069 if (a
[ODP_VPORT_ATTR_ADDRESS
]) {
1070 vport
->address
= nl_attr_get(a
[ODP_VPORT_ATTR_ADDRESS
]);
1072 if (a
[ODP_VPORT_ATTR_MTU
]) {
1073 vport
->mtu
= nl_attr_get_u32(a
[ODP_VPORT_ATTR_MTU
]);
1075 if (a
[ODP_VPORT_ATTR_OPTIONS
]) {
1076 vport
->options
= nl_attr_get(a
[ODP_VPORT_ATTR_OPTIONS
]);
1077 vport
->options_len
= nl_attr_get_size(a
[ODP_VPORT_ATTR_OPTIONS
]);
1079 if (a
[ODP_VPORT_ATTR_IFINDEX
]) {
1080 vport
->ifindex
= nl_attr_get_u32(a
[ODP_VPORT_ATTR_IFINDEX
]);
1082 if (a
[ODP_VPORT_ATTR_IFLINK
]) {
1083 vport
->iflink
= nl_attr_get_u32(a
[ODP_VPORT_ATTR_IFLINK
]);
1088 /* Appends to 'buf' (which must initially be empty) a "struct odp_header"
1089 * followed by Netlink attributes corresponding to 'vport'. */
1091 dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport
*vport
,
1094 struct odp_header
*odp_header
;
1096 nl_msg_put_genlmsghdr(buf
, 0, odp_vport_family
, NLM_F_REQUEST
| NLM_F_ECHO
,
1099 odp_header
= ofpbuf_put_uninit(buf
, sizeof *odp_header
);
1100 odp_header
->dp_ifindex
= vport
->dp_ifindex
;
1102 if (vport
->port_no
!= UINT32_MAX
) {
1103 nl_msg_put_u32(buf
, ODP_VPORT_ATTR_PORT_NO
, vport
->port_no
);
1106 if (vport
->type
!= ODP_VPORT_TYPE_UNSPEC
) {
1107 nl_msg_put_u32(buf
, ODP_VPORT_ATTR_TYPE
, vport
->type
);
1111 nl_msg_put_string(buf
, ODP_VPORT_ATTR_NAME
, vport
->name
);
1115 nl_msg_put_unspec(buf
, ODP_VPORT_ATTR_STATS
,
1116 vport
->stats
, sizeof *vport
->stats
);
1119 if (vport
->address
) {
1120 nl_msg_put_unspec(buf
, ODP_VPORT_ATTR_ADDRESS
,
1121 vport
->address
, ETH_ADDR_LEN
);
1125 nl_msg_put_u32(buf
, ODP_VPORT_ATTR_MTU
, vport
->mtu
);
1128 if (vport
->options
) {
1129 nl_msg_put_nested(buf
, ODP_VPORT_ATTR_OPTIONS
,
1130 vport
->options
, vport
->options_len
);
1133 if (vport
->ifindex
) {
1134 nl_msg_put_u32(buf
, ODP_VPORT_ATTR_IFINDEX
, vport
->ifindex
);
1137 if (vport
->iflink
) {
1138 nl_msg_put_u32(buf
, ODP_VPORT_ATTR_IFLINK
, vport
->iflink
);
1142 /* Clears 'vport' to "empty" values. */
1144 dpif_linux_vport_init(struct dpif_linux_vport
*vport
)
1146 memset(vport
, 0, sizeof *vport
);
1147 vport
->port_no
= UINT32_MAX
;
1150 /* Executes 'request' in the kernel datapath. If the command fails, returns a
1151 * positive errno value. Otherwise, if 'reply' and 'bufp' are null, returns 0
1152 * without doing anything else. If 'reply' and 'bufp' are nonnull, then the
1153 * result of the command is expected to be an odp_vport also, which is decoded
1154 * and stored in '*reply' and '*bufp'. The caller must free '*bufp' when the
1155 * reply is no longer needed ('reply' will contain pointers into '*bufp'). */
1157 dpif_linux_vport_transact(const struct dpif_linux_vport
*request
,
1158 struct dpif_linux_vport
*reply
,
1159 struct ofpbuf
**bufp
)
1161 struct ofpbuf
*request_buf
;
1164 assert((reply
!= NULL
) == (bufp
!= NULL
));
1166 request_buf
= ofpbuf_new(1024);
1167 dpif_linux_vport_to_ofpbuf(request
, request_buf
);
1168 error
= nl_sock_transact(genl_sock
, request_buf
, bufp
);
1169 ofpbuf_delete(request_buf
);
1173 error
= dpif_linux_vport_from_ofpbuf(reply
, *bufp
);
1176 dpif_linux_vport_init(reply
);
1177 ofpbuf_delete(*bufp
);
1184 /* Obtains information about the kernel vport named 'name' and stores it into
1185 * '*reply' and '*bufp'. The caller must free '*bufp' when the reply is no
1186 * longer needed ('reply' will contain pointers into '*bufp'). */
1188 dpif_linux_vport_get(const char *name
, struct dpif_linux_vport
*reply
,
1189 struct ofpbuf
**bufp
)
1191 struct dpif_linux_vport request
;
1193 dpif_linux_vport_init(&request
);
1194 request
.cmd
= ODP_VPORT_CMD_GET
;
1195 request
.name
= name
;
1197 return dpif_linux_vport_transact(&request
, reply
, bufp
);
1200 /* Parses the contents of 'buf', which contains a "struct odp_header" followed
1201 * by Netlink attributes, into 'dp'. Returns 0 if successful, otherwise a
1202 * positive errno value.
1204 * 'dp' will contain pointers into 'buf', so the caller should not free 'buf'
1205 * while 'dp' is still in use. */
1207 dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp
*dp
, const struct ofpbuf
*buf
)
1209 static const struct nl_policy odp_datapath_policy
[] = {
1210 [ODP_DP_ATTR_NAME
] = { .type
= NL_A_STRING
, .max_len
= IFNAMSIZ
},
1211 [ODP_DP_ATTR_STATS
] = { .type
= NL_A_UNSPEC
,
1212 .min_len
= sizeof(struct odp_stats
),
1213 .max_len
= sizeof(struct odp_stats
),
1215 [ODP_DP_ATTR_IPV4_FRAGS
] = { .type
= NL_A_U32
, .optional
= true },
1216 [ODP_DP_ATTR_SAMPLING
] = { .type
= NL_A_U32
, .optional
= true },
1217 [ODP_DP_ATTR_MCGROUPS
] = { .type
= NL_A_NESTED
, .optional
= true },
1220 struct nlattr
*a
[ARRAY_SIZE(odp_datapath_policy
)];
1221 struct odp_header
*odp_header
;
1222 struct nlmsghdr
*nlmsg
;
1223 struct genlmsghdr
*genl
;
1226 dpif_linux_dp_init(dp
);
1228 ofpbuf_use_const(&b
, buf
->data
, buf
->size
);
1229 nlmsg
= ofpbuf_try_pull(&b
, sizeof *nlmsg
);
1230 genl
= ofpbuf_try_pull(&b
, sizeof *genl
);
1231 odp_header
= ofpbuf_try_pull(&b
, sizeof *odp_header
);
1232 if (!nlmsg
|| !genl
|| !odp_header
1233 || nlmsg
->nlmsg_type
!= odp_datapath_family
1234 || !nl_policy_parse(&b
, 0, odp_datapath_policy
, a
,
1235 ARRAY_SIZE(odp_datapath_policy
))) {
1239 dp
->cmd
= genl
->cmd
;
1240 dp
->dp_ifindex
= odp_header
->dp_ifindex
;
1241 dp
->name
= nl_attr_get_string(a
[ODP_DP_ATTR_NAME
]);
1242 if (a
[ODP_DP_ATTR_STATS
]) {
1243 /* Can't use structure assignment because Netlink doesn't ensure
1244 * sufficient alignment for 64-bit members. */
1245 memcpy(&dp
->stats
, nl_attr_get(a
[ODP_DP_ATTR_STATS
]),
1248 if (a
[ODP_DP_ATTR_IPV4_FRAGS
]) {
1249 dp
->ipv4_frags
= nl_attr_get_u32(a
[ODP_DP_ATTR_IPV4_FRAGS
]);
1251 if (a
[ODP_DP_ATTR_SAMPLING
]) {
1252 dp
->sampling
= nl_attr_get(a
[ODP_DP_ATTR_SAMPLING
]);
1255 if (a
[ODP_DP_ATTR_MCGROUPS
]) {
1256 static const struct nl_policy odp_mcgroup_policy
[] = {
1257 [ODP_PACKET_CMD_MISS
] = { .type
= NL_A_U32
, .optional
= true },
1258 [ODP_PACKET_CMD_ACTION
] = { .type
= NL_A_U32
, .optional
= true },
1259 [ODP_PACKET_CMD_SAMPLE
] = { .type
= NL_A_U32
, .optional
= true },
1262 struct nlattr
*mcgroups
[ARRAY_SIZE(odp_mcgroup_policy
)];
1264 if (!nl_parse_nested(a
[ODP_DP_ATTR_MCGROUPS
], odp_mcgroup_policy
,
1265 mcgroups
, ARRAY_SIZE(odp_mcgroup_policy
))) {
1269 if (mcgroups
[ODP_PACKET_CMD_MISS
]) {
1270 dp
->mcgroups
[DPIF_UC_MISS
]
1271 = nl_attr_get_u32(mcgroups
[ODP_PACKET_CMD_MISS
]);
1273 if (mcgroups
[ODP_PACKET_CMD_ACTION
]) {
1274 dp
->mcgroups
[DPIF_UC_ACTION
]
1275 = nl_attr_get_u32(mcgroups
[ODP_PACKET_CMD_ACTION
]);
1277 if (mcgroups
[ODP_PACKET_CMD_SAMPLE
]) {
1278 dp
->mcgroups
[DPIF_UC_SAMPLE
]
1279 = nl_attr_get_u32(mcgroups
[ODP_PACKET_CMD_SAMPLE
]);
1286 /* Appends to 'buf' the Generic Netlink message described by 'dp'. */
1288 dpif_linux_dp_to_ofpbuf(const struct dpif_linux_dp
*dp
, struct ofpbuf
*buf
)
1290 struct odp_header
*odp_header
;
1292 nl_msg_put_genlmsghdr(buf
, 0, odp_datapath_family
,
1293 NLM_F_REQUEST
| NLM_F_ECHO
, dp
->cmd
, 1);
1295 odp_header
= ofpbuf_put_uninit(buf
, sizeof *odp_header
);
1296 odp_header
->dp_ifindex
= dp
->dp_ifindex
;
1299 nl_msg_put_string(buf
, ODP_DP_ATTR_NAME
, dp
->name
);
1302 /* Skip ODP_DP_ATTR_STATS since we never have a reason to serialize it. */
1304 if (dp
->ipv4_frags
) {
1305 nl_msg_put_u32(buf
, ODP_DP_ATTR_IPV4_FRAGS
, dp
->ipv4_frags
);
1309 nl_msg_put_u32(buf
, ODP_DP_ATTR_SAMPLING
, *dp
->sampling
);
1313 /* Clears 'dp' to "empty" values. */
1315 dpif_linux_dp_init(struct dpif_linux_dp
*dp
)
1317 memset(dp
, 0, sizeof *dp
);
1321 dpif_linux_dp_dump_start(struct nl_dump
*dump
)
1323 struct dpif_linux_dp request
;
1326 dpif_linux_dp_init(&request
);
1327 request
.cmd
= ODP_DP_CMD_GET
;
1329 buf
= ofpbuf_new(1024);
1330 dpif_linux_dp_to_ofpbuf(&request
, buf
);
1331 nl_dump_start(dump
, genl_sock
, buf
);
1335 /* Executes 'request' in the kernel datapath. If the command fails, returns a
1336 * positive errno value. Otherwise, if 'reply' and 'bufp' are null, returns 0
1337 * without doing anything else. If 'reply' and 'bufp' are nonnull, then the
1338 * result of the command is expected to be of the same form, which is decoded
1339 * and stored in '*reply' and '*bufp'. The caller must free '*bufp' when the
1340 * reply is no longer needed ('reply' will contain pointers into '*bufp'). */
1342 dpif_linux_dp_transact(const struct dpif_linux_dp
*request
,
1343 struct dpif_linux_dp
*reply
, struct ofpbuf
**bufp
)
1345 struct ofpbuf
*request_buf
;
1348 assert((reply
!= NULL
) == (bufp
!= NULL
));
1350 request_buf
= ofpbuf_new(1024);
1351 dpif_linux_dp_to_ofpbuf(request
, request_buf
);
1352 error
= nl_sock_transact(genl_sock
, request_buf
, bufp
);
1353 ofpbuf_delete(request_buf
);
1357 error
= dpif_linux_dp_from_ofpbuf(reply
, *bufp
);
1360 dpif_linux_dp_init(reply
);
1361 ofpbuf_delete(*bufp
);
1368 /* Obtains information about 'dpif_' and stores it into '*reply' and '*bufp'.
1369 * The caller must free '*bufp' when the reply is no longer needed ('reply'
1370 * will contain pointers into '*bufp'). */
1372 dpif_linux_dp_get(const struct dpif
*dpif_
, struct dpif_linux_dp
*reply
,
1373 struct ofpbuf
**bufp
)
1375 struct dpif_linux
*dpif
= dpif_linux_cast(dpif_
);
1376 struct dpif_linux_dp request
;
1378 dpif_linux_dp_init(&request
);
1379 request
.cmd
= ODP_DP_CMD_GET
;
1380 request
.dp_ifindex
= dpif
->dp_ifindex
;
1382 return dpif_linux_dp_transact(&request
, reply
, bufp
);
1385 /* Parses the contents of 'buf', which contains a "struct odp_header" followed
1386 * by Netlink attributes, into 'flow'. Returns 0 if successful, otherwise a
1387 * positive errno value.
1389 * 'flow' will contain pointers into 'buf', so the caller should not free 'buf'
1390 * while 'flow' is still in use. */
1392 dpif_linux_flow_from_ofpbuf(struct dpif_linux_flow
*flow
,
1393 const struct ofpbuf
*buf
)
1395 static const struct nl_policy odp_flow_policy
[] = {
1396 [ODP_FLOW_ATTR_KEY
] = { .type
= NL_A_NESTED
},
1397 [ODP_FLOW_ATTR_ACTIONS
] = { .type
= NL_A_NESTED
, .optional
= true },
1398 [ODP_FLOW_ATTR_STATS
] = { .type
= NL_A_UNSPEC
,
1399 .min_len
= sizeof(struct odp_flow_stats
),
1400 .max_len
= sizeof(struct odp_flow_stats
),
1402 [ODP_FLOW_ATTR_TCP_FLAGS
] = { .type
= NL_A_U8
, .optional
= true },
1403 [ODP_FLOW_ATTR_USED
] = { .type
= NL_A_U64
, .optional
= true },
1404 /* The kernel never uses ODP_FLOW_ATTR_CLEAR. */
1407 struct nlattr
*a
[ARRAY_SIZE(odp_flow_policy
)];
1408 struct odp_header
*odp_header
;
1409 struct nlmsghdr
*nlmsg
;
1410 struct genlmsghdr
*genl
;
1413 dpif_linux_flow_init(flow
);
1415 ofpbuf_use_const(&b
, buf
->data
, buf
->size
);
1416 nlmsg
= ofpbuf_try_pull(&b
, sizeof *nlmsg
);
1417 genl
= ofpbuf_try_pull(&b
, sizeof *genl
);
1418 odp_header
= ofpbuf_try_pull(&b
, sizeof *odp_header
);
1419 if (!nlmsg
|| !genl
|| !odp_header
1420 || nlmsg
->nlmsg_type
!= odp_flow_family
1421 || !nl_policy_parse(&b
, 0, odp_flow_policy
, a
,
1422 ARRAY_SIZE(odp_flow_policy
))) {
1426 flow
->nlmsg_flags
= nlmsg
->nlmsg_flags
;
1427 flow
->dp_ifindex
= odp_header
->dp_ifindex
;
1428 flow
->key
= nl_attr_get(a
[ODP_FLOW_ATTR_KEY
]);
1429 flow
->key_len
= nl_attr_get_size(a
[ODP_FLOW_ATTR_KEY
]);
1430 if (a
[ODP_FLOW_ATTR_ACTIONS
]) {
1431 flow
->actions
= nl_attr_get(a
[ODP_FLOW_ATTR_ACTIONS
]);
1432 flow
->actions_len
= nl_attr_get_size(a
[ODP_FLOW_ATTR_ACTIONS
]);
1434 if (a
[ODP_FLOW_ATTR_STATS
]) {
1435 flow
->stats
= nl_attr_get(a
[ODP_FLOW_ATTR_STATS
]);
1437 if (a
[ODP_FLOW_ATTR_TCP_FLAGS
]) {
1438 flow
->tcp_flags
= nl_attr_get(a
[ODP_FLOW_ATTR_TCP_FLAGS
]);
1443 /* Appends to 'buf' (which must initially be empty) a "struct odp_header"
1444 * followed by Netlink attributes corresponding to 'flow'. */
1446 dpif_linux_flow_to_ofpbuf(const struct dpif_linux_flow
*flow
,
1449 struct odp_header
*odp_header
;
1451 nl_msg_put_genlmsghdr(buf
, 0, odp_flow_family
,
1452 NLM_F_REQUEST
| flow
->nlmsg_flags
, flow
->cmd
, 1);
1454 odp_header
= ofpbuf_put_uninit(buf
, sizeof *odp_header
);
1455 odp_header
->dp_ifindex
= flow
->dp_ifindex
;
1457 if (flow
->key_len
) {
1458 nl_msg_put_unspec(buf
, ODP_FLOW_ATTR_KEY
, flow
->key
, flow
->key_len
);
1461 if (flow
->actions_len
) {
1462 nl_msg_put_unspec(buf
, ODP_FLOW_ATTR_ACTIONS
,
1463 flow
->actions
, flow
->actions_len
);
1466 /* We never need to send these to the kernel. */
1467 assert(!flow
->stats
);
1468 assert(!flow
->tcp_flags
);
1469 assert(!flow
->used
);
1472 nl_msg_put_flag(buf
, ODP_FLOW_ATTR_CLEAR
);
1476 /* Clears 'flow' to "empty" values. */
1478 dpif_linux_flow_init(struct dpif_linux_flow
*flow
)
1480 memset(flow
, 0, sizeof *flow
);
1483 /* Executes 'request' in the kernel datapath. If the command fails, returns a
1484 * positive errno value. Otherwise, if 'reply' and 'bufp' are null, returns 0
1485 * without doing anything else. If 'reply' and 'bufp' are nonnull, then the
1486 * result of the command is expected to be a flow also, which is decoded and
1487 * stored in '*reply' and '*bufp'. The caller must free '*bufp' when the reply
1488 * is no longer needed ('reply' will contain pointers into '*bufp'). */
1490 dpif_linux_flow_transact(const struct dpif_linux_flow
*request
,
1491 struct dpif_linux_flow
*reply
, struct ofpbuf
**bufp
)
1493 struct ofpbuf
*request_buf
;
1496 assert((reply
!= NULL
) == (bufp
!= NULL
));
1498 request_buf
= ofpbuf_new(1024);
1499 dpif_linux_flow_to_ofpbuf(request
, request_buf
);
1500 error
= nl_sock_transact(genl_sock
, request_buf
, bufp
);
1501 ofpbuf_delete(request_buf
);
1505 error
= dpif_linux_flow_from_ofpbuf(reply
, *bufp
);
1508 dpif_linux_flow_init(reply
);
1509 ofpbuf_delete(*bufp
);
1517 dpif_linux_flow_get_stats(const struct dpif_linux_flow
*flow
,
1518 struct dpif_flow_stats
*stats
)
1521 stats
->n_packets
= get_unaligned_u64(&flow
->stats
->n_packets
);
1522 stats
->n_bytes
= get_unaligned_u64(&flow
->stats
->n_bytes
);
1524 stats
->n_packets
= 0;
1527 stats
->used
= flow
->used
? get_unaligned_u64(flow
->used
) : 0;
1528 stats
->tcp_flags
= flow
->tcp_flags
? *flow
->tcp_flags
: 0;