cmp.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * lib/route/cls/ematch/cmp.c Simple packet data comparison ematch
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation version 2.1
  7. * of the License.
  8. *
  9. * Copyright (c) 2008-2013 Thomas Graf <tgraf@suug.ch>
  10. */
  11. /**
  12. * @ingroup ematch
  13. * @defgroup em_cmp Simple packet data comparison
  14. *
  15. * @{
  16. */
  17. #include <netlink-private/netlink.h>
  18. #include <netlink-private/tc.h>
  19. #include <netlink/netlink.h>
  20. #include <netlink/route/cls/ematch.h>
  21. #include <linux/tc_ematch/tc_em_cmp.h>
  22. void rtnl_ematch_cmp_set(struct rtnl_ematch *e, struct tcf_em_cmp *cfg)
  23. {
  24. memcpy(rtnl_ematch_data(e), cfg, sizeof(*cfg));
  25. }
  26. struct tcf_em_cmp *rtnl_ematch_cmp_get(struct rtnl_ematch *e)
  27. {
  28. return rtnl_ematch_data(e);
  29. }
  30. static int cmp_parse(struct rtnl_ematch *e, void *data, size_t len)
  31. {
  32. memcpy(rtnl_ematch_data(e), data, len);
  33. return 0;
  34. }
  35. static const char *align_txt[] = {
  36. [TCF_EM_ALIGN_U8] = "u8",
  37. [TCF_EM_ALIGN_U16] = "u16",
  38. [TCF_EM_ALIGN_U32] = "u32"
  39. };
  40. static const char *layer_txt[] = {
  41. [TCF_LAYER_LINK] = "eth",
  42. [TCF_LAYER_NETWORK] = "ip",
  43. [TCF_LAYER_TRANSPORT] = "tcp"
  44. };
  45. static const char *operand_txt[] = {
  46. [TCF_EM_OPND_EQ] = "=",
  47. [TCF_EM_OPND_LT] = "<",
  48. [TCF_EM_OPND_GT] = ">",
  49. };
  50. static void cmp_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
  51. {
  52. struct tcf_em_cmp *cmp = rtnl_ematch_data(e);
  53. if (cmp->flags & TCF_EM_CMP_TRANS)
  54. nl_dump(p, "ntoh%c(", (cmp->align == TCF_EM_ALIGN_U32) ? 'l' : 's');
  55. nl_dump(p, "%s at %s+%u",
  56. align_txt[cmp->align], layer_txt[cmp->layer], cmp->off);
  57. if (cmp->mask)
  58. nl_dump(p, " & 0x%x", cmp->mask);
  59. if (cmp->flags & TCF_EM_CMP_TRANS)
  60. nl_dump(p, ")");
  61. nl_dump(p, " %s %u", operand_txt[cmp->opnd], cmp->val);
  62. }
  63. static struct rtnl_ematch_ops cmp_ops = {
  64. .eo_kind = TCF_EM_CMP,
  65. .eo_name = "cmp",
  66. .eo_minlen = sizeof(struct tcf_em_cmp),
  67. .eo_datalen = sizeof(struct tcf_em_cmp),
  68. .eo_parse = cmp_parse,
  69. .eo_dump = cmp_dump,
  70. };
  71. static void __init cmp_init(void)
  72. {
  73. rtnl_ematch_register(&cmp_ops);
  74. }
  75. /** @} */