2 * Copyright (c) 2015 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.
20 #include <linux/netfilter/nfnetlink.h>
23 #include "netlink-conntrack.h"
24 #include "netlink-notifier.h"
26 #include "poll-loop.h"
30 enum nl_ct_event_type type
;
31 struct ct_dpif_entry entry
;
35 event_parse(struct ofpbuf
*buf
, void *change_
)
37 struct test_change
*change
= change_
;
39 if (nl_ct_parse_entry(buf
, &change
->entry
, &change
->type
)) {
40 switch (change
->type
) {
42 return NFNLGRP_CONNTRACK_NEW
;
43 case NL_CT_EVENT_UPDATE
:
44 return NFNLGRP_CONNTRACK_UPDATE
;
45 case NL_CT_EVENT_DELETE
:
46 return NFNLGRP_CONNTRACK_DESTROY
;
53 event_print(const void *change_
, void *aux OVS_UNUSED
)
55 const struct test_change
*change
= change_
;
58 struct ds ds
= DS_EMPTY_INITIALIZER
;
60 nl_ct_format_event_entry(&change
->entry
, change
->type
, &ds
, true,
62 printf("%s\n", ds_cstr(&ds
));
68 test_nl_ct_monitor(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
71 NFNLGRP_CONNTRACK_DESTROY
,
72 NFNLGRP_CONNTRACK_NEW
,
73 NFNLGRP_CONNTRACK_UPDATE
,
77 struct nln_notifier
*notifiers
[ARRAY_SIZE(groups
)];
79 struct test_change change
;
83 nln
= nln_create(NETLINK_NETFILTER
, event_parse
, &change
);
85 for (i
= 0; i
< ARRAY_SIZE(groups
); i
++) {
86 notifiers
[i
] = nln_notifier_create(nln
, groups
[i
], event_print
, NULL
);
95 for (i
= 0; i
< ARRAY_SIZE(groups
); i
++) {
96 nln_notifier_destroy(notifiers
[i
]);
103 test_nl_ct_dump(struct ovs_cmdl_context
*ctx
)
105 struct nl_ct_dump_state
*dump
;
106 uint16_t zone
, *pzone
= NULL
;
107 struct ct_dpif_entry entry
;
111 if (ctx
->argc
>= 2) {
112 if (!ovs_scan(ctx
->argv
[1], "zone=%"SCNu16
, &zone
)) {
113 ovs_fatal(0, "Error parsing zone= specifier");
117 err
= nl_ct_dump_start(&dump
, pzone
, &tot_bkts
);
119 ovs_fatal(err
, "Error creating conntrack netlink dump");
123 err
= nl_ct_dump_next(dump
, &entry
);
125 struct ds ds
= DS_EMPTY_INITIALIZER
;
127 ct_dpif_format_entry(&entry
, &ds
, true, true);
128 printf("%s\n", ds_cstr(&ds
));
134 ovs_fatal(err
, "Error dumping conntrack netlink entry");
136 nl_ct_dump_done(dump
);
141 test_nl_ct_flush(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
145 if (ctx
->argc
>= 2) {
148 if (ovs_scan(ctx
->argv
[1], "zone=%"SCNu16
, &zone
)) {
149 err
= nl_ct_flush_zone(zone
);
151 ovs_fatal(0, "Error parsing zone= specifier");
157 ovs_fatal(err
, "Error flushing conntrack netlink");
161 static const struct ovs_cmdl_command commands
[] = {
162 /* Linux netlink connection tracker interface test. */
164 /* Prints all the entries in the connection table and exits. */
165 {"dump", "[zone=zone]", 0, 1, test_nl_ct_dump
, OVS_RO
},
166 /* Listens to all the connection tracking events and prints them to
167 * standard output until killed. */
168 {"monitor", "", 0, 0, test_nl_ct_monitor
, OVS_RO
},
169 /* Flushes all the entries from all the tables.. */
170 {"flush", "[zone=zone]", 0, 1, test_nl_ct_flush
, OVS_RO
},
172 {NULL
, NULL
, 0, 0, NULL
, OVS_RO
},
176 test_netlink_conntrack(int argc
, char *argv
[])
178 struct ovs_cmdl_context ctx
= {
182 set_program_name(argv
[0]);
183 ovs_cmdl_run_command(&ctx
, commands
);
186 OVSTEST_REGISTER("test-netlink-conntrack", test_netlink_conntrack
);