aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/dpo/replicate_dpo.c
AgeCommit message (Expand)AuthorFilesLines
2023-05-19fib: fix load-balance and replicate dpos buckets overflowBenoît Ganne1-1/+15
2021-05-01vlib: refactor trajectory trace debug featureBenoît Ganne1-2/+0
2020-12-14misc: move to new pool_foreach macrosDamjan Marion1-3/+3
2020-04-11fib: fix accessing empty dpo pool elementsShivaShankarK1-1/+4
2019-08-15vlib: copy trace_handle in vlib_buffer_copy/clone() functionsJohn Lo1-4/+1
2018-12-18MFIB: recurse resolution through an MFIB entryNeale Ranns1-0/+88
2018-11-02vlib: define minimum chained buffer segment sizeDamjan Marion1-1/+2
2018-10-23c11 safe string handling supportDave Barach1-1/+1
2018-10-16FIB: use vlib-log for debuggingNeale Ranns1-11/+11
2018-10-08replicate trace fixNeale Ranns1-2/+6
2018-10-01mroute routers in the stats segmentNeale Ranns1-1/+6
2018-02-06BIER: fix support for longer bit-string lengthsNeale Ranns1-1/+2
2017-11-09BIERNeale Ranns1-7/+7
2017-04-07MPLS McastNeale Ranns1-7/+41
2017-04-06Use thread local storage for thread indexDamjan Marion1-6/+6
2017-02-28vlib: add buffer cloning supportDamjan Marion1-44/+32
2017-02-24VPP-650: handle buffer failure in vlib_buffer_copy(...)Dave Barach1-1/+31
2017-02-03Next node frame over-flow after replicationNeale Ranns1-2/+16
2017-02-02Fix SR multicast post mfib commitNeale Ranns1-9/+5
2017-01-27IP Multicast FIB (mfib)Neale Ranns1-0/+759
color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 * Copyright (c) 2017-2019 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

#include <vppinfra/error.h>

u8 RT (rule_is_exact_match) (RTT (mma_rule) * key, RTT (mma_rule) * r)
{
  int i;

  for (i = 0; i < ARRAY_LEN (key->match.as_u64); i++)
    {
      if (key->match.as_u64[i] != r->match.as_u64[i])
	return 0;
    }
  for (i = 0; i < ARRAY_LEN (key->mask.as_u64); i++)
    {
      if (key->mask.as_u64[i] != r->mask.as_u64[i])
	return 0;
    }
  return 1;
}

u8
RT (rule_is_match_for_key) (RTT (mma_mask_or_match) * key, RTT (mma_rule) * r)
{
  RTT (mma_mask_or_match) _tmp_key, *tkp = &_tmp_key;
  int i;

  *tkp = *key;
  for (i = 0; i < ARRAY_LEN (tkp->as_u64); i++)
    tkp->as_u64[i] &= r->mask.as_u64[i];
  for (i = 0; i < ARRAY_LEN (tkp->as_u64); i++)
    {
      if (tkp->as_u64[i] != r->match.as_u64[i])
	return 0;
    }
  return 1;
}

RTT (mma_rule) * RT (mma_rules_table_rule_alloc) (RTT (mma_rules_table) * srt)
{
  RTT (mma_rule) * rule;
  pool_get (srt->rules, rule);
  clib_memset (rule, 0, sizeof (*rule));
  return rule;
}

RTT (mma_rule) *
RT (mma_rule_free) (RTT (mma_rules_table) * srt, RTT (mma_rule) * rule)
{
  pool_put (srt->rules, rule);
  clib_memset (rule, 0xfa, sizeof (*rule));
  return rule;
}

RTT (mma_rule) *
RT (mma_rules_table_get_rule) (RTT (mma_rules_table) * srt, u32 srt_index)
{
  if (!pool_is_free_index (srt->rules, srt_index))
    return (srt->rules + srt_index);
  return 0;
}

u32
RT (mma_rules_table_rule_index) (RTT (mma_rules_table) * srt,
				 RTT (mma_rule) * sr)
{
  ASSERT (sr);
  return (sr - srt->rules);
}

/**
 * Lookup key in table
 *
 * This should be optimized .. eventually
 */
u32
RT (mma_rules_table_lookup) (RTT (mma_rules_table) * srt,
			     RTT (mma_mask_or_match) * key, u32 rule_index)
{
  RTT (mma_rule) * rp;
  u32 rv;
  int i;

  ASSERT (rule_index != MMA_TABLE_INVALID_INDEX);
  rp = RT (mma_rules_table_get_rule) (srt, rule_index);
  ASSERT (rp);

  if (!RT (rule_is_match_for_key) (key, rp))
    return MMA_TABLE_INVALID_INDEX;
  for (i = 0; i < vec_len (rp->next_indices); i++)
    {
      rv = RT (mma_rules_table_lookup) (srt, key, rp->next_indices[i]);
      if (rv != MMA_TABLE_INVALID_INDEX)
	return (rv);
    }
  return (rp->action_index);
}

u32
RT (mma_rules_table_lookup_rule) (RTT (mma_rules_table) * srt,
				  RTT (mma_mask_or_match) * key,
				  u32 rule_index)
{
  RTT (mma_rule) * rp;
  u32 rv;
  int i;

  ASSERT (rule_index != MMA_TABLE_INVALID_INDEX);
  rp = RT (mma_rules_table_get_rule) (srt, rule_index);
  ASSERT (rp);

  if (!RT (rule_is_match_for_key) (key, rp))
    return MMA_TABLE_INVALID_INDEX;
  for (i = 0; i < vec_len (rp->next_indices); i++)
    {
      rv = RT (mma_rules_table_lookup_rule) (srt, key, rp->next_indices[i]);
      if (rv != MMA_TABLE_INVALID_INDEX)
	return (rv);
    }
  return rule_index;
}

static
RTT (mma_rules_table) *
RTT (sort_srt);

     int RT (mma_sort_indices) (void *e1, void *e2)
{
  u32 *ri1 = e1, *ri2 = e2;
  RTT (mma_rule) * rule1, *rule2;
  rule1 = RT (mma_rules_table_get_rule) (RTT (sort_srt), *ri1);
  rule2 = RT (mma_rules_table_get_rule) (RTT (sort_srt), *ri2);
  return RTT (sort_srt)->rule_cmp_fn (rule1, rule2);
}

void RT (mma_sort) (RTT (mma_rules_table) * srt, u32 * next_indices)
{
  RTT (sort_srt) = srt;
  vec_sort_with_function (next_indices, RT (mma_sort_indices));
}

int
RT (mma_rules_table_add_rule) (RTT (mma_rules_table) * srt,
			       RTT (mma_rule) * rule)
{
  u32 parent_index, i, *next_indices = 0, added = 0, rule_index;
  RTT (mma_rule) * parent, *child;

  rule_index = RT (mma_rules_table_rule_index) (srt, rule);
  parent_index = RT (mma_rules_table_lookup_rule) (srt, &rule->match,
						   srt->root_index);
  parent = RT (mma_rules_table_get_rule) (srt, parent_index);
  if (RT (rule_is_exact_match) (rule, parent))
    {
      parent->action_index = rule->action_index;
      RT (mma_rule_free) (srt, rule);
      return -1;
    }

  if (vec_len (parent->next_indices) == 0)
    {
      vec_add1 (parent->next_indices, rule_index);
      return 0;
    }

  /* Check if new rule is parent of some of the existing children */
  for (i = 0; i < vec_len (parent->next_indices); i++)
    {
      child = RT (mma_rules_table_get_rule) (srt, parent->next_indices[i]);
      if (RT (rule_is_match_for_key) (&child->match, rule))
	{
	  vec_add1 (rule->next_indices, parent->next_indices[i]);
	  if (!added)
	    {
	      vec_add1 (next_indices, rule_index);
	      added = 1;
	    }
	}
      else
	{
	  if (!added && srt->rule_cmp_fn (rule, child) < 0)
	    {
	      vec_add1 (next_indices, rule_index);
	      added = 1;
	    }
	  vec_add1 (next_indices, parent->next_indices[i]);
	}
    }
  if (!added)
    vec_add1 (next_indices, rule_index);
  vec_free (parent->next_indices);
  parent->next_indices = next_indices;
  return 0;
}

int
RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt,
			       RTT (mma_rule) * rule, u32 rule_index)
{
  RTT (mma_rule) * rp;
  u32 rv;
  int i;

  ASSERT (rule_index != MMA_TABLE_INVALID_INDEX);
  rp = RT (mma_rules_table_get_rule) (srt, rule_index);

  if (!RT (rule_is_match_for_key) (&rule->match, rp))
    return MMA_TABLE_INVALID_INDEX;
  if (RT (rule_is_exact_match) (rule, rp))
    {
      if (rule_index == srt->root_index)
	rp->action_index = MMA_TABLE_INVALID_INDEX;
      return 1;
    }
  for (i = 0; i < vec_len (rp->next_indices); i++)
    {
      rv = RT (mma_rules_table_del_rule) (srt, rule, rp->next_indices[i]);
      if (rv == 1)
	{
	  RTT (mma_rule) * child;
	  u32 *next_indices = 0, *new_elts, left_to_add;
	  child = RT (mma_rules_table_get_rule) (srt, rp->next_indices[i]);
	  ASSERT (RT (rule_is_exact_match) (rule, child));

	  if (i != 0)
	    {
	      vec_add2 (next_indices, new_elts, i);
	      clib_memcpy_fast (new_elts, rp->next_indices, i * sizeof (u32));
	    }
	  if (vec_len (child->next_indices))
	    vec_append (next_indices, child->next_indices);
	  left_to_add = vec_len (rp->next_indices) - i - 1;
	  if (left_to_add)
	    {
	      vec_add2 (next_indices, new_elts, left_to_add);
	      clib_memcpy_fast (new_elts, &rp->next_indices[i + 1],
				left_to_add * sizeof (u32));
	    }
	  RT (mma_rule_free) (srt, child);
	  vec_free (rp->next_indices);
	  rp->next_indices = next_indices;
	  return 0;
	}
      else if (rv == 0)
	return rv;
    }
  return MMA_TABLE_INVALID_INDEX;
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */