aboutsummaryrefslogtreecommitdiffstats
path: root/resources/libraries/bash/shell
AgeCommit message (Expand)AuthorFilesLines
2019-08-08Remove: Obsolete bash codePeter Mikus2-173/+0
2018-09-26CSIT-1316 Fix ligato building mechanics in CSIT bootstrapsPeter Mikus1-1/+1
2018-03-26Optimize Qemu installation to speed up vhost testsPeter Mikus1-19/+19
2018-01-02CSIT-870 Kubernetes/Ligato integrationPeter Mikus3-0/+298
ae81ff } /* Literal */ .highlight .n { color: #f8f8f2 } /* Name */ .highlight .o { color: #f92672 } /* Operator */ .highlight .p { color: #f8f8f2 } /* Punctuation */ .highlight .ch { color: #75715e } /* Comment.Hashbang */ .highlight .cm { color: #75715e } /* Comment.Multiline */ .highlight .cp { color: #75715e } /* Comment.Preproc */ .highlight .cpf { color: #75715e } /* Comment.PreprocFile */ .highlight .c1 { color: #75715e } /* Comment.Single */ .highlight .cs { color: #75715e } /* Comment.Special */ .highlight .gd { color: #f92672 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gi { color: #a6e22e } /* Generic.Inserted */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #75715e } /* Generic.Subheading */ .highlight .kc { color: #66d9ef } /* Keyword.Constant */ .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ .highlight .kn { color: #f92672 } /* Keyword.Namespace */ .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ .highlight .kt { color: #66d9ef } /* Keyword.Type */ .highlight .ld { color: #e6db74 } /* Literal.Date */ .highlight .m { color: #ae81ff } /* Literal.Number */ .highlight .s { color: #e6db74 } /* Literal.String */ .highlight .na { color: #a6e22e } /* Name.Attribute */ .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ .highlight .nc { color: #a6e22e } /* Name.Class */ .highlight .no { color: #66d9ef } /* Name.Constant */ .highlight .nd { color: #a6e22e } /* Name.Decorator */ .highlight .ni { color: #f8f8f2 } /* Name.Entity */ .highlight .ne { color: #a6e22e } /* Name.Exception */ .highlight .nf { color: #a6e22e } /* Name.Function */ .highlight .nl { color: #f8f8f2 } /* Name.Label */ .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ .highlight .nx { color: #a6e22e } /* Name.Other */ .highlight .py { color: #f8f8f2 } /* Name.Property */ .highlight .nt { color: #f92672 } /* Name.Tag */ .highlight .nv { color: #f8f8f2 } /* Name.Variable */ .highlight .ow { color: #f92672 } /* Operator.Word */ .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ .highlight .mb { color: #ae81ff } /* Literal.Number.Bin */ .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ .highlight .sa { color: #e6db74 } /* Literal.String.Affix */ .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ .highlight .sc { color: #e6db74 } /* Literal.String.Char */ .highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */ .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ .highlight .se { color: #ae81ff } /* Literal.String.Escape */ .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ .highlight .sx { color: #e6db74 } /* Literal.String.Other */ .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-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) 2018 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 <igmp/igmp_query.h>
#include <igmp/igmp_pkt.h>

static f64
igmp_get_random_resp_delay (const igmp_header_t * header)
{
  u32 seed;

  seed = vlib_time_now (vlib_get_main ());

  return ((random_f64 (&seed) * igmp_header_get_max_resp_time (header)));

}

static ip46_address_t *
igmp_query_mk_source_list (const igmp_membership_query_v3_t * q)
{
  ip46_address_t *srcs = NULL;
  const ip4_address_t *s;
  u16 ii, n;

  /*
   * we validated this packet when we accepted it in the DP, so
   * this number is safe to use
   */
  n = clib_net_to_host_u16 (q->n_src_addresses);

  if (0 == n)
    return (NULL);

  vec_validate (srcs, n - 1);
  s = q->src_addresses;

  for (ii = 0; ii < n; ii++)
    {
      srcs[ii].ip4 = *s;
      s++;
    }

  return (srcs);
}

static void
igmp_send_group_report_v3 (u32 obj, void *data)
{
  igmp_pkt_build_report_t br;
  igmp_config_t *config;
  ip46_address_t *srcs;
  igmp_group_t *group;
  igmp_main_t *im;

  im = &igmp_main;
  srcs = data;
  group = pool_elt_at_index (im->groups, obj);
  config = pool_elt_at_index (im->configs, group->config);

  igmp_pkt_build_report_init (&br, config->sw_if_index);
  ASSERT (group->timers[IGMP_GROUP_TIMER_QUERY_REPLY] !=
	  IGMP_TIMER_ID_INVALID);

  IGMP_DBG ("send-group-report: %U",
	    format_vnet_sw_if_index_name,
	    vnet_get_main (), config->sw_if_index);

  if (NULL == srcs)
    {
      /*
       * there were no sources specified, so this is a group-specific query.
       * We should respond with all our sources
       */
      igmp_pkt_report_v3_add_group (&br, group,
				    IGMP_MEMBERSHIP_GROUP_mode_is_include);
    }
  else
    {
      /*
       * the sources stored in the timer object are the combined set of sources
       * to be required. We need to respond only to those queried, not our full set.
       */
      ip46_address_t *intersect;

      intersect = igmp_group_new_intersect_present (group,
						    IGMP_FILTER_MODE_INCLUDE,
						    srcs);

      if (vec_len (intersect))
	{
	  igmp_pkt_report_v3_add_report (&br,
					 group->key,
					 intersect,
					 IGMP_MEMBERSHIP_GROUP_mode_is_include);
	  vec_free (intersect);
	}
    }

  igmp_pkt_report_v3_send (&br);

  igmp_timer_retire (&group->timers[IGMP_GROUP_TIMER_QUERY_REPLY]);
  vec_free (srcs);
}

static igmp_membership_group_v3_type_t
igmp_filter_mode_to_report_type (igmp_filter_mode_t mode)
{
  switch (mode)
    {
    case IGMP_FILTER_MODE_INCLUDE:
      return (IGMP_MEMBERSHIP_GROUP_mode_is_include);
    case IGMP_FILTER_MODE_EXCLUDE:
      return (IGMP_MEMBERSHIP_GROUP_mode_is_exclude);
    }

  return (IGMP_MEMBERSHIP_GROUP_mode_is_include);
}

/**
 * Send igmp membership general report.
 */
static void
igmp_send_general_report_v3 (u32 obj, void *data)
{
  igmp_pkt_build_report_t br;
  igmp_config_t *config;
  igmp_group_t *group;
  igmp_main_t *im;

  im = &igmp_main;
  config = pool_elt_at_index (im->configs, obj);

  ASSERT (config->timers[IGMP_CONFIG_TIMER_GENERAL_REPORT] !=
	  IGMP_TIMER_ID_INVALID);

  igmp_timer_retire (&config->timers[IGMP_CONFIG_TIMER_GENERAL_REPORT]);

  IGMP_DBG ("send-general-report: %U",
	    format_vnet_sw_if_index_name,
	    vnet_get_main (), config->sw_if_index);

  igmp_pkt_build_report_init (&br, config->sw_if_index);

  /* *INDENT-OFF* */
  FOR_EACH_GROUP (group, config,
    ({
      igmp_pkt_report_v3_add_group
        (&br, group,
         igmp_filter_mode_to_report_type(group->router_filter_mode));
    }));
  /* *INDENT-ON* */

  igmp_pkt_report_v3_send (&br);
}

/**
 * Called from the main thread on reception of a Query message
 */
void
igmp_handle_query (const igmp_query_args_t * args)
{
  igmp_config_t *config;

  config = igmp_config_lookup (args->sw_if_index);

  if (!config)
    /*
     * no IGMP config on the interface. quit
     */
    return;

  if (IGMP_MODE_ROUTER == config->mode)
    {
      ASSERT (0);
      // code here for querier election */
    }

  IGMP_DBG ("query-rx: %U", format_vnet_sw_if_index_name,
	    vnet_get_main (), args->sw_if_index);


  /*
     Section 5.2
     "When a system receives a Query, it does not respond immediately.
     Instead, it delays its response by a random amount of time, bounded
     by the Max Resp Time value derived from the Max Resp Code in the
     received Query message.  A system may receive a variety of Queries on
     different interfaces and of different kinds (e.g., General Queries,
     Group-Specific Queries, and Group-and-Source-Specific Queries), each
     of which may require its own delayed response.
   */
  if (igmp_membership_query_v3_is_general (args->query))
    {
      IGMP_DBG ("...general-query-rx: %U", format_vnet_sw_if_index_name,
		vnet_get_main (), args->sw_if_index);

      /*
       * A general query has no info that needs saving from the response
       */
      if (IGMP_TIMER_ID_INVALID ==
	  config->timers[IGMP_CONFIG_TIMER_GENERAL_REPORT])
	{
	  f64 delay = igmp_get_random_resp_delay (&args->query[0].header);

	  IGMP_DBG ("...general-query-rx: %U schedule for %f",
		    format_vnet_sw_if_index_name, vnet_get_main (),
		    args->sw_if_index, delay);

	  /*
	   * no currently running timer, schedule a new one
	   */
	  config->timers[IGMP_CONFIG_TIMER_GENERAL_REPORT] =
	    igmp_timer_schedule (delay,
				 igmp_config_index (config),
				 igmp_send_general_report_v3, NULL);
	}
      /*
       * else
       *  don't reschedule timers, we'll reply soon enough..
       */
    }
  else
    {
      /*
       * G or SG query. we'll need to save the sources quered
       */
      igmp_key_t key = {
	.ip4 = args->query[0].group_address,
      };
      ip46_address_t *srcs;
      igmp_timer_id_t tid;
      igmp_group_t *group;

      group = igmp_group_lookup (config, &key);

      /*
       * If there is no group config, no worries, we can ignore this
       * query. If the group state does come soon, we'll send a
       * state-change report at that time.
       */
      if (!group)
	return;

      srcs = igmp_query_mk_source_list (args->query);
      tid = group->timers[IGMP_GROUP_TIMER_QUERY_REPLY];

      IGMP_DBG ("...group-query-rx: %U for (%U, %U)",
		format_vnet_sw_if_index_name,
		vnet_get_main (), args->sw_if_index,
		format_igmp_src_addr_list, srcs, format_igmp_key, &key);


      if (IGMP_TIMER_ID_INVALID != tid)
	{
	  /*
	   * There is a timer already running, merge the sources list
	   */
	  ip46_address_t *current, *s;

	  current = igmp_timer_get_data (tid);

	  vec_foreach (s, srcs)
	  {
	    if (~0 == vec_search_with_function (current, s,
						ip46_address_is_equal))
	      {
		vec_add1 (current, *s);
	      }
	  }

	  igmp_timer_set_data (tid, current);
	}
      else
	{
	  /*
	   * schedule a new G-specific query
	   */
	  f64 delay = igmp_get_random_resp_delay (&args->query[0].header);

	  IGMP_DBG ("...group-query-rx: schedule:%f", delay);

	  group->timers[IGMP_GROUP_TIMER_QUERY_REPLY] =
	    igmp_timer_schedule (delay,
				 igmp_group_index (group),
				 igmp_send_group_report_v3, srcs);
	}
    }
}


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