summaryrefslogtreecommitdiffstats
path: root/src/plugins/vrrp/vrrp.c
diff options
context:
space:
mode:
authorMatthew Smith <mgsmith@netgate.com>2021-12-21 09:00:05 -0600
committerMatthew Smith <mgsmith@netgate.com>2022-01-03 15:45:43 -0600
commitfa74a64def2132fb0c81e981547ac65888751aa9 (patch)
tree6fafb6f327c086fba7bc0f5edd41afcbcfd39c2e /src/plugins/vrrp/vrrp.c
parenta3d8c2c21472c3088fb770d60d111fd5c55d9225 (diff)
vrrp: fix support for VRs in different FIBs
Type: fix Fixes: 4b1b13315a3c When adding or deleting a VR, multicast routes can be added or deleted. When the first VR is added, a local (dpo-receive) route is added. The route is deleted when the last VR is deleted. Perform the check on whether to add or delete the route on a per-FIB basis. Otherwise, if the route is only added after the first VR is added without regards to the FIB being used and a second VR is added later on an interface attached to a different FIB, the necessary route will not be added to the FIB used by the second interface. Change-Id: Ib30925ecf45c714cfe3ac6a223754bea918f10e3 Signed-off-by: Matthew Smith <mgsmith@netgate.com>
Diffstat (limited to 'src/plugins/vrrp/vrrp.c')
-rw-r--r--src/plugins/vrrp/vrrp.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/src/plugins/vrrp/vrrp.c b/src/plugins/vrrp/vrrp.c
index b6817b8a55c..dbc122c5bd9 100644
--- a/src/plugins/vrrp/vrrp.c
+++ b/src/plugins/vrrp/vrrp.c
@@ -384,10 +384,9 @@ static int
vrrp_intf_enable_disable_mcast (u8 enable, u32 sw_if_index, u8 is_ipv6)
{
vrrp_main_t *vrm = &vrrp_main;
- vrrp_vr_t *vr;
vrrp_intf_t *intf;
- u32 fib_index;
- u32 n_vrs = 0;
+ u32 fib_index, i;
+ u32 n_vrs_in_fib = 0;
const mfib_prefix_t *vrrp_prefix;
fib_protocol_t proto;
vnet_link_t link_type;
@@ -422,20 +421,19 @@ vrrp_intf_enable_disable_mcast (u8 enable, u32 sw_if_index, u8 is_ipv6)
via_itf.frp_proto = fib_proto_to_dpo (proto);
fib_index = mfib_table_get_index_for_sw_if_index (proto, sw_if_index);
- /* *INDENT-OFF* */
- pool_foreach (vr, vrm->vrs)
- {
- if (vrrp_vr_is_ipv6 (vr) == is_ipv6)
- n_vrs++;
- }
- /* *INDENT-ON* */
+ vec_foreach_index (i, vrm->vrrp_intfs)
+ {
+ if (mfib_table_get_index_for_sw_if_index (proto, i) != fib_index)
+ continue;
+
+ n_vrs_in_fib += vrrp_intf_num_vrs (i, is_ipv6);
+ }
if (enable)
{
- /* If this is the first VR configured, add the local mcast routes */
- if (n_vrs == 1)
- mfib_table_entry_path_update (fib_index, vrrp_prefix, MFIB_SOURCE_API,
- MFIB_ENTRY_FLAG_NONE, &for_us);
+ /* ensure that the local mcast route exists */
+ mfib_table_entry_path_update (fib_index, vrrp_prefix, MFIB_SOURCE_API,
+ MFIB_ENTRY_FLAG_NONE, &for_us);
mfib_table_entry_path_update (fib_index, vrrp_prefix, MFIB_SOURCE_API,
MFIB_ENTRY_FLAG_NONE, &via_itf);
@@ -445,7 +443,7 @@ vrrp_intf_enable_disable_mcast (u8 enable, u32 sw_if_index, u8 is_ipv6)
else
{
/* Remove mcast local routes if this is the last VR being deleted */
- if (n_vrs == 0)
+ if (n_vrs_in_fib == 0)
mfib_table_entry_path_remove (fib_index, vrrp_prefix, MFIB_SOURCE_API,
&for_us);
/* 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.
 */

#ifndef included_time_range_h
#define included_time_range_h

#include <vppinfra/format.h>
#include <vppinfra/time.h>

typedef enum
{
  CLIB_TIMEBASE_DAYLIGHT_NONE = 0,
  CLIB_TIMEBASE_DAYLIGHT_USA,
} clib_timebase_daylight_time_t;

typedef struct
{
  /* provides f64 seconds since clib_time_init was called */
  clib_time_t *clib_time;
  f64 timezone_offset;
  f64 summer_offset;
  clib_timebase_daylight_time_t daylight_time_type;
  f64 cached_year_start;
  f64 cached_year_end;
  f64 cached_summer_start;
  f64 cached_summer_end;
} clib_timebase_t;

typedef struct
{
  u32 year, month, day, hour, minute, second, nanosecond;
  /* 0 => Thursday */
  u32 day_name_index;
  f64 fractional_seconds;
} clib_timebase_component_t;

typedef struct
{
  f64 start, end;
} clib_timebase_range_t;

void clib_timebase_init (clib_timebase_t * tb, i32 timezone_offset_in_hours,
			 clib_timebase_daylight_time_t daylight_type,
			 clib_time_t * clib_time);

void clib_timebase_time_to_components (f64 now,
				       clib_timebase_component_t * cp);

f64 clib_timebase_components_to_time (clib_timebase_component_t * cp);

f64 clib_timebase_find_sunday_midnight (f64 start_time);
f64 clib_timebase_offset_from_sunday (u8 * day);
f64 clib_timebase_summer_offset (clib_timebase_t * tb, f64 now);

unformat_function_t unformat_clib_timebase_range_hms;
unformat_function_t unformat_clib_timebase_range_vector;

format_function_t format_clib_timebase_time;

static inline f64 clib_timebase_summer_offset_fastpath
  (clib_timebase_t * tb, f64 now)
{
  if (PREDICT_TRUE
      (now >= tb->cached_year_start && now <= tb->cached_year_end))
    {
      if (now >= tb->cached_summer_start && now <= tb->cached_summer_end)
	return tb->summer_offset;
      else
	return 0.0;
    }
  else
    return clib_timebase_summer_offset (tb, now);
}

static inline f64
clib_timebase_now (clib_timebase_t * tb)
{
  f64 now;

  now = tb->clib_time->init_reference_time + clib_time_now (tb->clib_time);
  now += tb->timezone_offset;
  now += clib_timebase_summer_offset_fastpath (tb, now);

  return now;
}

static inline int
clib_timebase_is_leap_year (u32 year)
{
  int rv;

  if (PREDICT_TRUE ((year % 4) != 0))
    return 0;

  rv = 0;

  if ((year % 4) == 0)
    rv = 1;
  if ((year % 100) == 0)
    rv = 0;
  if ((year % 400) == 0)
    rv = 1;
  return rv;
}

#endif /* included_time_range_h */


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