Esempio n. 1
0
static clib_error_t *
adj_mcast_interface_state_change (vnet_main_t * vnm,
				  u32 sw_if_index,
				  u32 flags)
{
    /*
     * for each mcast on the interface trigger a walk back to the children
     */
    fib_protocol_t proto;
    ip_adjacency_t *adj;


    for (proto = FIB_PROTOCOL_IP4; proto <= FIB_PROTOCOL_IP6; proto++)
    {
	if (sw_if_index >= vec_len(adj_mcasts[proto]) ||
	    ADJ_INDEX_INVALID == adj_mcasts[proto][sw_if_index])
	    continue;

	adj = adj_get(adj_mcasts[proto][sw_if_index]);

	fib_node_back_walk_ctx_t bw_ctx = {
	    .fnbw_reason = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP ?
			    FIB_NODE_BW_REASON_FLAG_INTERFACE_UP :
			    FIB_NODE_BW_REASON_FLAG_INTERFACE_DOWN),
	};

	fib_walk_sync(FIB_NODE_TYPE_ADJ, adj_get_index(adj), &bw_ctx);
    }

    return (NULL);
}

VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(adj_mcast_interface_state_change);

/**
 * @brief Invoked on each SW interface of a HW interface when the
 * HW interface state changes
 */
static walk_rc_t
adj_mcast_hw_sw_interface_state_change (vnet_main_t * vnm,
                                        u32 sw_if_index,
                                        void *arg)
{
    adj_mcast_interface_state_change(vnm, sw_if_index, (uword) arg);

    return (WALK_CONTINUE);
}
Esempio n. 2
0
static clib_error_t *
adj_mcast_interface_delete (vnet_main_t * vnm,
			    u32 sw_if_index,
			    u32 is_add)
{
    /*
     * for each mcast on the interface trigger a walk back to the children
     */
    fib_protocol_t proto;
    ip_adjacency_t *adj;

    if (is_add)
    {
	/*
	 * not interested in interface additions. we will not back walk
	 * to resolve paths through newly added interfaces. Why? The control
	 * plane should have the brains to add interfaces first, then routes.
	 * So the case where there are paths with a interface that matches
	 * one just created is the case where the path resolved through an
	 * interface that was deleted, and still has not been removed. The
	 * new interface added, is NO GUARANTEE that the interface being
	 * added now, even though it may have the same sw_if_index, is the
	 * same interface that the path needs. So tough!
	 * If the control plane wants these routes to resolve it needs to
	 * remove and add them again.
	 */
	return (NULL);
    }

    for (proto = FIB_PROTOCOL_IP4; proto <= FIB_PROTOCOL_IP6; proto++)
    {
	if (sw_if_index >= vec_len(adj_mcasts[proto]) ||
	    ADJ_INDEX_INVALID == adj_mcasts[proto][sw_if_index])
	    continue;

	adj = adj_get(adj_mcasts[proto][sw_if_index]);

	fib_node_back_walk_ctx_t bw_ctx = {
	    .fnbw_reason =  FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE,
	};

	fib_walk_sync(FIB_NODE_TYPE_ADJ, adj_get_index(adj), &bw_ctx);
    }

    return (NULL);
}
Esempio n. 3
0
void
abf_policy_update (u32 policy_id,
		   u32 acl_index, const fib_route_path_t * rpaths)
{
  abf_policy_t *ap;
  u32 api;

  api = abf_policy_find (policy_id);

  if (INDEX_INVALID == api)
    {
      /*
       * create a new policy
       */
      pool_get (abf_policy_pool, ap);

      api = ap - abf_policy_pool;
      fib_node_init (&ap->ap_node, abf_policy_fib_node_type);
      ap->ap_acl = acl_index;
      ap->ap_id = policy_id;
      ap->ap_pl = fib_path_list_create ((FIB_PATH_LIST_FLAG_SHARED |
					 FIB_PATH_LIST_FLAG_NO_URPF), rpaths);

      /*
       * become a child of the path list so we get poked when
       * the forwarding changes.
       */
      ap->ap_sibling = fib_path_list_child_add (ap->ap_pl,
						abf_policy_fib_node_type,
						api);

      /*
       * add this new policy to the DB
       */
      hash_set (abf_policy_db, policy_id, api);

      /*
       * take a lock on behalf of the CLI/API creation
       */
      fib_node_lock (&ap->ap_node);
    }
  else
    {
      /*
       * update an existing policy.
       * - add the path to the path-list and swap our ancestry
       * - backwalk to poke all attachments to update
       */
      fib_node_index_t old_pl;

      ap = abf_policy_get (api);
      old_pl = ap->ap_pl;

      if (FIB_NODE_INDEX_INVALID != old_pl)
	{
	  ap->ap_pl = fib_path_list_copy_and_path_add (old_pl,
						       (FIB_PATH_LIST_FLAG_SHARED
							|
							FIB_PATH_LIST_FLAG_NO_URPF),
						       rpaths);
	  fib_path_list_child_remove (old_pl, ap->ap_sibling);
	}
      else
	{
	  ap->ap_pl = fib_path_list_create ((FIB_PATH_LIST_FLAG_SHARED |
					     FIB_PATH_LIST_FLAG_NO_URPF),
					    rpaths);
	}

      ap->ap_sibling = fib_path_list_child_add (ap->ap_pl,
						abf_policy_fib_node_type,
						api);

      fib_node_back_walk_ctx_t ctx = {
	.fnbw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE,
      };

      fib_walk_sync (abf_policy_fib_node_type, api, &ctx);
    }
}
Esempio n. 4
0
int
abf_policy_delete (u32 policy_id, const fib_route_path_t * rpaths)
{
  abf_policy_t *ap;
  u32 api;

  api = abf_policy_find (policy_id);

  if (INDEX_INVALID == api)
    {
      /*
       * no such policy
       */
      return (-1);
    }
  else
    {
      /*
       * update an existing policy.
       * - add the path to the path-list and swap our ancestry
       * - backwalk to poke all attachments to update
       */
      fib_node_index_t old_pl;

      ap = abf_policy_get (api);
      old_pl = ap->ap_pl;

      fib_path_list_lock (old_pl);
      ap->ap_pl =
	fib_path_list_copy_and_path_remove (ap->ap_pl,
					    (FIB_PATH_LIST_FLAG_SHARED |
					     FIB_PATH_LIST_FLAG_NO_URPF),
					    rpaths);

      fib_path_list_child_remove (old_pl, ap->ap_sibling);
      ap->ap_sibling = ~0;

      if (FIB_NODE_INDEX_INVALID == ap->ap_pl)
	{
	  /*
	   * no more paths on this policy. It's toast
	   * remove the CLI/API's lock
	   */
	  fib_node_unlock (&ap->ap_node);
	}
      else
	{
	  ap->ap_sibling = fib_path_list_child_add (ap->ap_pl,
						    abf_policy_fib_node_type,
						    api);

	  fib_node_back_walk_ctx_t ctx = {
	    .fnbw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE,
	  };

	  fib_walk_sync (abf_policy_fib_node_type, api, &ctx);
	}
      fib_path_list_unlock (old_pl);
    }

  return (0);
}