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.
19 #include <linux/netfilter/nfnetlink.h>
22 #include "netlink-conntrack.h"
23 #include "netlink-notifier.h"
25 #include "poll-loop.h"
29 enum nl_ct_event_type type;
30 struct ct_dpif_entry entry;
34 event_parse(struct ofpbuf *buf, void *change_)
36 struct test_change *change = change_;
38 if (nl_ct_parse_entry(buf, &change->entry, &change->type)) {
39 switch (change->type) {
41 return NFNLGRP_CONNTRACK_NEW;
42 case NL_CT_EVENT_UPDATE:
43 return NFNLGRP_CONNTRACK_UPDATE;
44 case NL_CT_EVENT_DELETE:
45 return NFNLGRP_CONNTRACK_DESTROY;
52 event_print(const void *change_, void *aux OVS_UNUSED)
54 const struct test_change *change = change_;
57 struct ds ds = DS_EMPTY_INITIALIZER;
59 nl_ct_format_event_entry(&change->entry, change->type, &ds, true,
61 printf("%s\n", ds_cstr(&ds));
67 test_nl_ct_monitor(struct ovs_cmdl_context *ctx OVS_UNUSED)
70 NFNLGRP_CONNTRACK_DESTROY,
71 NFNLGRP_CONNTRACK_NEW,
72 NFNLGRP_CONNTRACK_UPDATE,
76 struct nln_notifier *notifiers[ARRAY_SIZE(groups)];
78 struct test_change change;
82 nln = nln_create(NETLINK_NETFILTER, event_parse, &change);
84 for (i = 0; i < ARRAY_SIZE(groups); i++) {
85 notifiers[i] = nln_notifier_create(nln, groups[i], event_print, NULL);
94 for (i = 0; i < ARRAY_SIZE(groups); i++) {
95 nln_notifier_destroy(notifiers[i]);
102 test_nl_ct_dump(struct ovs_cmdl_context *ctx)
104 struct nl_ct_dump_state *dump;
105 uint16_t zone, *pzone = NULL;
106 struct ct_dpif_entry entry;
109 if (ctx->argc >= 2) {
110 if (!ovs_scan(ctx->argv[1], "zone=%"SCNu16, &zone)) {
111 ovs_fatal(0, "Error parsing zone= specifier");
115 err = nl_ct_dump_start(&dump, pzone);
117 ovs_fatal(err, "Error creating conntrack netlink dump");
121 err = nl_ct_dump_next(dump, &entry);
123 struct ds ds = DS_EMPTY_INITIALIZER;
125 ct_dpif_format_entry(&entry, &ds, true, true);
126 printf("%s\n", ds_cstr(&ds));
132 ovs_fatal(err, "Error dumping conntrack netlink entry");
134 nl_ct_dump_done(dump);
139 test_nl_ct_flush(struct ovs_cmdl_context *ctx OVS_UNUSED)
143 if (ctx->argc >= 2) {
146 if (ovs_scan(ctx->argv[1], "zone=%"SCNu16, &zone)) {
147 err = nl_ct_flush_zone(zone);
149 ovs_fatal(0, "Error parsing zone= specifier");
155 ovs_fatal(err, "Error flushing conntrack netlink");
159 static const struct ovs_cmdl_command commands[] = {
160 /* Linux netlink connection tracker interface test. */
162 /* Prints all the entries in the connection table and exits. */
163 {"dump", "[zone=zone]", 0, 1, test_nl_ct_dump},
164 /* Listens to all the connection tracking events and prints them to
165 * standard output until killed. */
166 {"monitor", "", 0, 0, test_nl_ct_monitor},
167 /* Flushes all the entries from all the tables.. */
168 {"flush", "[zone=zone]", 0, 1, test_nl_ct_flush},
170 {NULL, NULL, 0, 0, NULL},
174 test_netlink_conntrack(int argc, char *argv[])
176 struct ovs_cmdl_context ctx = {
180 set_program_name(argv[0]);
181 ovs_cmdl_run_command(&ctx, commands);
184 OVSTEST_REGISTER("test-netlink-conntrack", test_netlink_conntrack);