summaryrefslogtreecommitdiffstats
path: root/src/nl-pktloc-lookup.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2010-10-26 23:21:50 (GMT)
committerThomas Graf <tgraf@suug.ch>2010-10-26 23:21:50 (GMT)
commit65e386c8ba490d405f539322a12e1f1c7ea2eb5c (patch)
tree155a0dafacd32619123042f926a8d1638b28ed8b /src/nl-pktloc-lookup.c
parentb57a697ef1053a70264e9bedea3d2b98b8b24019 (diff)
downloadlibnl-65e386c8ba490d405f539322a12e1f1c7ea2eb5c.zip
libnl-65e386c8ba490d405f539322a12e1f1c7ea2eb5c.tar.gz
libnl-65e386c8ba490d405f539322a12e1f1c7ea2eb5c.tar.bz2
Packet location updates
This patch includes various bugfixes in the packet location parser. Namely it removes two memory leaks if parsing fails. The parser is correctly quit if an allocation error occurs and it is no longer possible to add duplicates. It removes the possibility to differ between net and host byteorder. This is better done in the actual classifiers as it makes more sense to specify this together with the value to compare against. The patch also extends the API to add new packet locations via rtnl_pktloc_add(). It introduces reference counting, therefore you now have to give back packet locations with rtnl_pktloc_put() after looking them up with rtnl_pktloc_lookup(). But you are allowed to keep using them if the packet location file has been reread. The packet location file now also understands "eth", "ip", and "tcp" for "link", "net", and "transport". A --list option has been added to nl-pktloc-lookup to list all packet location definitions A --u32=VALUE option has been added to let nl-pktloc-lookup print the definition in iproute2's u32 selector style. A manual page has been written for nl-pktloc-lookup. Finally, nl-pktloc-lookup has been made installable.
Diffstat (limited to 'src/nl-pktloc-lookup.c')
-rw-r--r--src/nl-pktloc-lookup.c111
1 files changed, 105 insertions, 6 deletions
diff --git a/src/nl-pktloc-lookup.c b/src/nl-pktloc-lookup.c
index 09b04b2..dc6154f 100644
--- a/src/nl-pktloc-lookup.c
+++ b/src/nl-pktloc-lookup.c
@@ -14,24 +14,123 @@
static void print_usage(void)
{
- printf("Usage: nl-pktloc-lookup <name>\n");
+printf(
+"Usage: nl-pktloc-lookup [OPTIONS] <name>\n"
+"\n"
+"OPTIONS\n"
+" -h, --help Show this help text.\n"
+" -v, --version Show versioning information.\n"
+" -l, --list List all packet location definitions.\n"
+" --u32=VALUE Print in iproute2's u32 selector style\n"
+"\n"
+"\n"
+"EXAMPLE\n"
+" $ nl-pktloc-lookup ip.dst\n"
+" $ nl-pktloc-lookup --list\n"
+"\n"
+);
exit(0);
}
+static const char *align_txt[] = {
+ [TCF_EM_ALIGN_U8] = "u8",
+ [TCF_EM_ALIGN_U16] = "u16",
+ [TCF_EM_ALIGN_U32] = "u32"
+};
+
+static uint32_t align_mask[] = {
+ [TCF_EM_ALIGN_U8] = 0xff,
+ [TCF_EM_ALIGN_U16] = 0xffff,
+ [TCF_EM_ALIGN_U32] = 0xffffffff,
+};
+
+static const char *layer_txt[] = {
+ [TCF_LAYER_LINK] = "eth",
+ [TCF_LAYER_NETWORK] = "ip",
+ [TCF_LAYER_TRANSPORT] = "tcp"
+};
+
+static void dump_u32_style(struct rtnl_pktloc *loc, uint32_t value)
+{
+ if (loc->layer == TCF_LAYER_LINK)
+ nl_cli_fatal(EINVAL, "u32 does not support link "
+ "layer locations.");
+
+ printf("%s %x %x at %s%u\n",
+ align_txt[loc->align],
+ value, loc->mask ? loc->mask : align_mask[loc->align],
+ loc->layer == TCF_LAYER_TRANSPORT ? "nexthdr+" : "",
+ loc->offset);
+}
+
+static void dump_loc(struct rtnl_pktloc *loc)
+{
+ printf("%s = %s at %s+%u %#x\n",
+ loc->name, align_txt[loc->align],
+ layer_txt[loc->layer], loc->offset, loc->mask);
+}
+
+static void list_cb(struct rtnl_pktloc *loc, void *arg)
+{
+ printf("%-26s %-5s %3s+%-4u %#-10x %u\n",
+ loc->name, align_txt[loc->align],
+ layer_txt[loc->layer], loc->offset,
+ loc->mask, loc->refcnt);
+}
+
+static void do_list(void)
+{
+ printf("name align offset mask refcnt\n");
+ printf("---------------------------------------------------------\n");
+
+ rtnl_pktloc_foreach(&list_cb, NULL);
+}
+
int main(int argc, char *argv[])
{
struct rtnl_pktloc *loc;
- int err;
+ int err, ustyle = 0;
+ uint32_t uvalue = 0;
+
+ for (;;) {
+ int c, optidx = 0;
+ enum {
+ ARG_U32 = 257,
+ };
+ static struct option long_opts[] = {
+ { "help", 0, 0, 'h' },
+ { "version", 0, 0, 'v' },
+ { "list", 0, 0, 'l' },
+ { "u32", 1, 0, ARG_U32 },
+ { 0, 0, 0, 0 }
+ };
+
+ c = getopt_long(argc, argv, "hvl", long_opts, &optidx);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'h': print_usage(); break;
+ case 'v': nl_cli_print_version(); break;
+ case 'l': do_list(); exit(0);
+ case ARG_U32:
+ ustyle = 1;
+ uvalue = nl_cli_parse_u32(optarg);
+ break;
+ }
+ }
- if (argc < 2)
+ if (optind >= argc)
print_usage();
- if ((err = rtnl_pktloc_lookup(argv[1], &loc)) < 0)
+ if ((err = rtnl_pktloc_lookup(argv[optind++], &loc)) < 0)
nl_cli_fatal(err, "Unable to lookup packet location: %s",
nl_geterror(err));
- printf("%s: %u %u+%u 0x%x %u\n", loc->name, loc->align,
- loc->layer, loc->offset, loc->mask, loc->flags);
+ if (ustyle)
+ dump_u32_style(loc, uvalue);
+ else
+ dump_loc(loc);
return 0;
}