611-netfilter_match_bypass_default_table.patch 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. --- a/net/ipv4/netfilter/ip_tables.c
  2. +++ b/net/ipv4/netfilter/ip_tables.c
  3. @@ -308,6 +308,33 @@ struct ipt_entry *ipt_next_entry(const s
  4. return (void *)entry + entry->next_offset;
  5. }
  6. +static bool
  7. +ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict)
  8. +{
  9. + struct xt_entry_target *t;
  10. + struct xt_standard_target *st;
  11. +
  12. + if (e->target_offset != sizeof(struct ipt_entry))
  13. + return false;
  14. +
  15. + if (!(e->ip.flags & IPT_F_NO_DEF_MATCH))
  16. + return false;
  17. +
  18. + t = ipt_get_target(e);
  19. + if (t->u.kernel.target->target)
  20. + return false;
  21. +
  22. + st = (struct xt_standard_target *) t;
  23. + if (st->verdict == XT_RETURN)
  24. + return false;
  25. +
  26. + if (st->verdict >= 0)
  27. + return false;
  28. +
  29. + *verdict = (unsigned)(-st->verdict) - 1;
  30. + return true;
  31. +}
  32. +
  33. /* Returns one of the generic firewall policies, like NF_ACCEPT. */
  34. unsigned int
  35. ipt_do_table(struct sk_buff *skb,
  36. @@ -328,28 +355,8 @@ ipt_do_table(struct sk_buff *skb,
  37. unsigned int addend;
  38. /* Initialization */
  39. - stackidx = 0;
  40. - ip = ip_hdr(skb);
  41. - indev = state->in ? state->in->name : nulldevname;
  42. - outdev = state->out ? state->out->name : nulldevname;
  43. - /* We handle fragments by dealing with the first fragment as
  44. - * if it was a normal packet. All other fragments are treated
  45. - * normally, except that they will NEVER match rules that ask
  46. - * things we don't know, ie. tcp syn flag or ports). If the
  47. - * rule is also a fragment-specific rule, non-fragments won't
  48. - * match it. */
  49. - acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
  50. - acpar.thoff = ip_hdrlen(skb);
  51. - acpar.hotdrop = false;
  52. - acpar.net = state->net;
  53. - acpar.in = state->in;
  54. - acpar.out = state->out;
  55. - acpar.family = NFPROTO_IPV4;
  56. - acpar.hooknum = hook;
  57. -
  58. IP_NF_ASSERT(table->valid_hooks & (1 << hook));
  59. local_bh_disable();
  60. - addend = xt_write_recseq_begin();
  61. private = table->private;
  62. cpu = smp_processor_id();
  63. /*
  64. @@ -358,6 +365,23 @@ ipt_do_table(struct sk_buff *skb,
  65. */
  66. smp_read_barrier_depends();
  67. table_base = private->entries;
  68. +
  69. + e = get_entry(table_base, private->hook_entry[hook]);
  70. + if (ipt_handle_default_rule(e, &verdict)) {
  71. + struct xt_counters *counter;
  72. +
  73. + counter = xt_get_this_cpu_counter(&e->counters);
  74. + ADD_COUNTER(*counter, skb->len, 1);
  75. + local_bh_enable();
  76. + return verdict;
  77. + }
  78. +
  79. + stackidx = 0;
  80. + ip = ip_hdr(skb);
  81. + indev = state->in ? state->in->name : nulldevname;
  82. + outdev = state->out ? state->out->name : nulldevname;
  83. +
  84. + addend = xt_write_recseq_begin();
  85. jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
  86. /* Switch to alternate jumpstack if we're being invoked via TEE.
  87. @@ -370,7 +394,20 @@ ipt_do_table(struct sk_buff *skb,
  88. if (static_key_false(&xt_tee_enabled))
  89. jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
  90. - e = get_entry(table_base, private->hook_entry[hook]);
  91. + /* We handle fragments by dealing with the first fragment as
  92. + * if it was a normal packet. All other fragments are treated
  93. + * normally, except that they will NEVER match rules that ask
  94. + * things we don't know, ie. tcp syn flag or ports). If the
  95. + * rule is also a fragment-specific rule, non-fragments won't
  96. + * match it. */
  97. + acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
  98. + acpar.thoff = ip_hdrlen(skb);
  99. + acpar.hotdrop = false;
  100. + acpar.net = state->net;
  101. + acpar.in = state->in;
  102. + acpar.out = state->out;
  103. + acpar.family = NFPROTO_IPV4;
  104. + acpar.hooknum = hook;
  105. pr_debug("Entering %s(hook %u), UF %p\n",
  106. table->name, hook,