#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
-#include <dlfcn.h>
#include <errno.h>
#include "m_ematch.h"
"where: OBJECT := { META_ID | VALUE }\n" \
" META_ID := id [ shift SHIFT ] [ mask MASK ]\n" \
"\n" \
- "Example: meta(nfmark gt 24)\n" \
- " meta(indev shift 1 eq \"ppp\"\n" \
+ "Example: meta(nf_mark gt 24)\n" \
+ " meta(indev shift 1 eq \"ppp\")\n" \
" meta(tcindex mask 0xf0 eq 0xf0)\n" \
- " meta(dev eq indev)\n" \
"\n" \
"For a list of meta identifiers, use meta(list).\n");
}
-struct meta_entry {
+static const struct meta_entry {
int id;
- char * kind;
- char * mask;
- char * desc;
+ char *kind;
+ char *mask;
+ char *desc;
} meta_table[] = {
#define TCF_META_ID_SECTION 0
#define __A(id, name, mask, desc) { TCF_META_ID_##id, name, mask, desc }
__A(SECTION, "Interfaces", "", ""),
__A(DEV, "dev", "iv",
"Device the packet is on"),
- __A(INDEV, "indev", "iv",
- "Device the packet came in"),
- __A(REALDEV, "realdev", "iv",
- "Underlying real device"),
-
__A(SECTION, "Packet attributes", "", ""),
__A(PRIORITY, "priority", "i",
"Priority of packet"),
__A(PROTOCOL, "protocol", "i",
"Link layer protocol"),
- __A(SECURITY, "security", "i",
- "Security level"),
__A(PKTTYPE, "pkt_type", "i",
"Packet type (uni|multi|broad|...)cast"),
__A(PKTLEN, "pkt_len", "i",
__A(SECTION, "Traffic Control", "", ""),
__A(TCINDEX, "tc_index", "i", "TC Index"),
- __A(TCVERDICT, "tc_verdict", "i", "TC Verdict"),
- __A(TCCLASSID, "tc_classid", "i", "TC ClassID"),
-
__A(SECTION, "Routing", "", ""),
__A(RTCLASSID, "rt_classid", "i",
"Routing ClassID (cls_route)"),
__A(RTIIF, "rt_iif", "i",
"Incoming interface index"),
+ __A(VLAN_TAG, "vlan", "i", "Vlan tag"),
__A(SECTION, "Sockets", "", ""),
__A(SK_FAMILY, "sk_family", "i", "Address family"),
__A(SK_RMEM_ALLOC, "sk_rmem", "i", "RMEM"),
__A(SK_WMEM_ALLOC, "sk_wmem", "i", "WMEM"),
__A(SK_OMEM_ALLOC, "sk_omem", "i", "OMEM"),
- __A(SK_WMEM_QUEUED, "sk_wmem_queue","i", "WMEM queue"),
+ __A(SK_WMEM_QUEUED, "sk_wmem_queue", "i", "WMEM queue"),
__A(SK_SND_QLEN, "sk_snd_queue", "i", "Send queue length"),
__A(SK_RCV_QLEN, "sk_rcv_queue", "i", "Receive queue length"),
__A(SK_ERR_QLEN, "sk_err_queue", "i", "Error queue length"),
return INT_MAX;
}
-static struct meta_entry * lookup_meta_entry(struct bstr *kind)
+static const struct meta_entry *lookup_meta_entry(struct bstr *kind)
{
int i;
- for (i = 0; i < (sizeof(meta_table)/sizeof(meta_table[0])); i++)
+ for (i = 0; i < ARRAY_SIZE(meta_table); i++)
if (!bstrcmp(kind, meta_table[i].kind) &&
meta_table[i].id != 0)
return &meta_table[i];
-
+
return NULL;
}
-static struct meta_entry * lookup_meta_entry_byid(int id)
+static const struct meta_entry *lookup_meta_entry_byid(int id)
{
int i;
- for (i = 0; i < (sizeof(meta_table)/sizeof(meta_table[0])); i++)
+ for (i = 0; i < ARRAY_SIZE(meta_table); i++)
if (meta_table[i].id == id)
return &meta_table[i];
-
+
return NULL;
}
case TCF_META_TYPE_VAR:
if (TCF_META_ID(hdr->kind) == TCF_META_ID_VALUE) {
struct bstr *a = (struct bstr *) val;
+
addattr_l(n, MAX_MSG, tlv, a->data, a->len);
}
break;
static inline int is_compatible(struct tcf_meta_val *what,
struct tcf_meta_val *needed)
{
+ const struct meta_entry *entry;
char *p;
- struct meta_entry *entry;
-
+
entry = lookup_meta_entry_byid(TCF_META_ID(what->kind));
if (entry == NULL)
return 0;
-
+
for (p = entry->mask; p; p++)
if (map_type(*p) == TCF_META_TYPE(needed->kind))
return 1;
" ID Type Description\n" \
"--------------------------------------------------------");
- for (i = 0; i < (sizeof(meta_table)/sizeof(meta_table[0])); i++) {
+ for (i = 0; i < ARRAY_SIZE(meta_table); i++) {
if (meta_table[i].id == TCF_META_ID_SECTION) {
fprintf(fd, "\n%s:\n", meta_table[i].kind);
} else {
#define PARSE_FAILURE ((void *) (-1))
#define PARSE_ERR(CARG, FMT, ARGS...) \
- em_parse_error(EINVAL, args, CARG, &meta_ematch_util, FMT ,##ARGS)
+ em_parse_error(EINVAL, args, CARG, &meta_ematch_util, FMT, ##ARGS)
static inline int can_adopt(struct tcf_meta_val *val)
{
{
return (TCF_META_TYPE(dst->kind) << 12) | TCF_META_ID(src->kind);
}
-
+
static inline struct bstr *
parse_object(struct bstr *args, struct bstr *arg, struct tcf_meta_val *obj,
unsigned long *dst, struct tcf_meta_val *left)
{
- struct meta_entry *entry;
+ const struct meta_entry *entry;
unsigned long num;
struct bstr *a;
}
num = bstrtoul(arg);
- if (num != LONG_MAX) {
+ if (num != ULONG_MAX) {
obj->kind = TCF_META_TYPE_INT << 12;
obj->kind |= TCF_META_ID_VALUE;
*dst = (unsigned long) num;
if (left) {
struct tcf_meta_val *right = obj;
-
+
if (TCF_META_TYPE(right->kind) == TCF_META_TYPE(left->kind))
goto compatible;
right->kind = overwrite_type(right, left);
else
goto not_compatible;
- } else
+ } else
goto not_compatible;
}
a = bstr_next(arg);
- while(a) {
+ while (a) {
if (!bstrcmp(a, "shift")) {
unsigned long shift;
return PARSE_FAILURE;
}
a = bstr_next(a);
-
+
shift = bstrtoul(a);
- if (shift == LONG_MAX) {
+ if (shift == ULONG_MAX) {
PARSE_ERR(a, "meta: invalid shift, must " \
"be numeric");
return PARSE_FAILURE;
return PARSE_FAILURE;
}
a = bstr_next(a);
-
+
mask = bstrtoul(a);
- if (mask == LONG_MAX) {
+ if (mask == ULONG_MAX) {
PARSE_ERR(a, "meta: invalid mask, must be " \
"numeric");
return PARSE_FAILURE;
{
int opnd;
struct bstr *a;
- struct tcf_meta_hdr meta_hdr;
+ struct tcf_meta_hdr meta_hdr = {};
unsigned long lvalue = 0, rvalue = 0;
- memset(&meta_hdr, 0, sizeof(meta_hdr));
-
if (args == NULL)
return PARSE_ERR(args, "meta: missing arguments");
return -1;
else if (a != NULL)
return PARSE_ERR(a, "meta: unexpected trailer");
-
+
addraw_l(n, MAX_MSG, hdr, sizeof(*hdr));
addattr_l(n, MAX_MSG, TCA_EM_META_HDR, &meta_hdr, sizeof(meta_hdr));
- if (lvalue)
- dump_value(n, TCA_EM_META_LVALUE, lvalue, &meta_hdr.left);
-
- if (rvalue)
- dump_value(n, TCA_EM_META_RVALUE, rvalue, &meta_hdr.right);
+ dump_value(n, TCA_EM_META_LVALUE, lvalue, &meta_hdr.left);
+ dump_value(n, TCA_EM_META_RVALUE, rvalue, &meta_hdr.right);
return 0;
}
return -1;
}
- switch(type) {
+ switch (type) {
case TCF_META_TYPE_INT:
if (RTA_PAYLOAD(rta) < sizeof(__u32)) {
fprintf(stderr, "meta int type value TLV " \
"size mismatch.\n");
return -1;
}
- fprintf(fd, "%d", *(__u32 *) RTA_DATA(rta));
+ fprintf(fd, "%d", rta_getattr_u32(rta));
break;
case TCF_META_TYPE_VAR:
{
int id = TCF_META_ID(obj->kind);
int type = TCF_META_TYPE(obj->kind);
- struct meta_entry *entry;
+ const struct meta_entry *entry;
if (id == TCF_META_ID_VALUE)
return print_value(fd, type, rta);
if (RTA_PAYLOAD(rta) < sizeof(__u32))
goto size_mismatch;
- fprintf(fd, " mask 0x%08x",
- *(__u32*) RTA_DATA(rta));
+ if (rta_getattr_u32(rta))
+ fprintf(fd, " mask 0x%08x",
+ rta_getattr_u32(rta));
}
break;
}