diff options
Diffstat (limited to 'eigrpd/eigrp_interface.c')
| -rw-r--r-- | eigrpd/eigrp_interface.c | 810 | 
1 files changed, 390 insertions, 420 deletions
diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index a9deafe257..2312cc6edd 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -54,470 +54,448 @@  #include "eigrpd/eigrp_topology.h"  #include "eigrpd/eigrp_memory.h" -static void -eigrp_delete_from_if (struct interface *, struct eigrp_interface *); +static void eigrp_delete_from_if(struct interface *, struct eigrp_interface *); -static void -eigrp_add_to_if (struct interface *ifp, struct eigrp_interface *ei) +static void eigrp_add_to_if(struct interface *ifp, struct eigrp_interface *ei)  { -  struct route_node *rn; -  struct prefix p; - -  p = *ei->address; -  p.prefixlen = IPV4_MAX_PREFIXLEN; - -  rn = route_node_get (IF_OIFS (ifp), &p); -  /* rn->info should either be NULL or equal to this ei -   * as route_node_get may return an existing node -   */ -  assert (!rn->info || rn->info == ei); -  rn->info = ei; +	struct route_node *rn; +	struct prefix p; + +	p = *ei->address; +	p.prefixlen = IPV4_MAX_PREFIXLEN; + +	rn = route_node_get(IF_OIFS(ifp), &p); +	/* rn->info should either be NULL or equal to this ei +	 * as route_node_get may return an existing node +	 */ +	assert(!rn->info || rn->info == ei); +	rn->info = ei;  } -struct eigrp_interface * -eigrp_if_new (struct eigrp *eigrp, struct interface *ifp, struct prefix *p) +struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, +				     struct prefix *p)  { -  struct eigrp_interface *ei; -  int i; +	struct eigrp_interface *ei; +	int i; -  if ((ei = eigrp_if_table_lookup (ifp, p)) == NULL) -    { -      ei = XCALLOC (MTYPE_EIGRP_IF, sizeof (struct eigrp_interface)); -      memset (ei, 0, sizeof (struct eigrp_interface)); -    } -  else -    return ei; +	if ((ei = eigrp_if_table_lookup(ifp, p)) == NULL) { +		ei = XCALLOC(MTYPE_EIGRP_IF, sizeof(struct eigrp_interface)); +		memset(ei, 0, sizeof(struct eigrp_interface)); +	} else +		return ei; -  /* Set zebra interface pointer. */ -  ei->ifp = ifp; -  ei->address = p; +	/* Set zebra interface pointer. */ +	ei->ifp = ifp; +	ei->address = p; -  eigrp_add_to_if (ifp, ei); -  listnode_add (eigrp->eiflist, ei); +	eigrp_add_to_if(ifp, ei); +	listnode_add(eigrp->eiflist, ei); -  ei->type = EIGRP_IFTYPE_BROADCAST; +	ei->type = EIGRP_IFTYPE_BROADCAST; -  /* Initialize neighbor list. */ -  ei->nbrs = list_new (); +	/* Initialize neighbor list. */ +	ei->nbrs = list_new(); -  ei->crypt_seqnum = time (NULL); +	ei->crypt_seqnum = time(NULL); -  /* Initialize lists */ -  for (i = 0; i < EIGRP_FILTER_MAX; i++) -    { -      ei->list[i] = NULL; -      ei->prefix[i] = NULL; -      ei->routemap[i] = NULL; -    } +	/* Initialize lists */ +	for (i = 0; i < EIGRP_FILTER_MAX; i++) { +		ei->list[i] = NULL; +		ei->prefix[i] = NULL; +		ei->routemap[i] = NULL; +	} -  return ei; +	return ei;  }  /* lookup ei for specified prefix/ifp */ -struct eigrp_interface * -eigrp_if_table_lookup (struct interface *ifp, struct prefix *prefix) +struct eigrp_interface *eigrp_if_table_lookup(struct interface *ifp, +					      struct prefix *prefix)  { -  struct prefix p; -  struct route_node *rn; -  struct eigrp_interface *rninfo = NULL; +	struct prefix p; +	struct route_node *rn; +	struct eigrp_interface *rninfo = NULL; -  p = *prefix; -  p.prefixlen = IPV4_MAX_PREFIXLEN; +	p = *prefix; +	p.prefixlen = IPV4_MAX_PREFIXLEN; -  /* route_node_get implicitly locks */ -  if ((rn = route_node_lookup (IF_OIFS (ifp), &p))) -    { -      rninfo = (struct eigrp_interface *) rn->info; -      route_unlock_node (rn); -    } +	/* route_node_get implicitly locks */ +	if ((rn = route_node_lookup(IF_OIFS(ifp), &p))) { +		rninfo = (struct eigrp_interface *)rn->info; +		route_unlock_node(rn); +	} -  return rninfo; +	return rninfo;  } -int -eigrp_if_delete_hook (struct interface *ifp) +int eigrp_if_delete_hook(struct interface *ifp)  { -  struct route_node *rn; +	struct route_node *rn; -  route_table_finish (IF_OIFS (ifp)); +	route_table_finish(IF_OIFS(ifp)); -  for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn)) -    if (rn->info) -      eigrp_del_if_params (rn->info); -  route_table_finish (IF_OIFS_PARAMS (ifp)); +	for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn)) +		if (rn->info) +			eigrp_del_if_params(rn->info); +	route_table_finish(IF_OIFS_PARAMS(ifp)); -  XFREE (MTYPE_EIGRP_IF_INFO, ifp->info); -  ifp->info = NULL; +	XFREE(MTYPE_EIGRP_IF_INFO, ifp->info); +	ifp->info = NULL; -  return 0; +	return 0;  }  struct list *eigrp_iflist; -void -eigrp_if_init () +void eigrp_if_init()  { -  /* Initialize Zebra interface data structure. */ -  if_add_hook (IF_NEW_HOOK, eigrp_if_new_hook); -  if_add_hook (IF_DELETE_HOOK, eigrp_if_delete_hook); +	/* Initialize Zebra interface data structure. */ +	if_add_hook(IF_NEW_HOOK, eigrp_if_new_hook); +	if_add_hook(IF_DELETE_HOOK, eigrp_if_delete_hook);  } -int -eigrp_if_new_hook (struct interface *ifp) +int eigrp_if_new_hook(struct interface *ifp)  { -  int rc = 0; +	int rc = 0; -  ifp->info = XCALLOC (MTYPE_EIGRP_IF_INFO, sizeof (struct eigrp_if_info)); +	ifp->info = XCALLOC(MTYPE_EIGRP_IF_INFO, sizeof(struct eigrp_if_info)); -  IF_OIFS (ifp) = route_table_init (); -  IF_OIFS_PARAMS (ifp) = route_table_init (); +	IF_OIFS(ifp) = route_table_init(); +	IF_OIFS_PARAMS(ifp) = route_table_init(); -  IF_DEF_PARAMS (ifp) = eigrp_new_if_params (); +	IF_DEF_PARAMS(ifp) = eigrp_new_if_params(); -  SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello); -  IF_DEF_PARAMS (ifp)->v_hello = (u_int32_t) EIGRP_HELLO_INTERVAL_DEFAULT; +	SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello); +	IF_DEF_PARAMS(ifp)->v_hello = (u_int32_t)EIGRP_HELLO_INTERVAL_DEFAULT; -  SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait); -  IF_DEF_PARAMS (ifp)->v_wait = (u_int16_t) EIGRP_HOLD_INTERVAL_DEFAULT; +	SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait); +	IF_DEF_PARAMS(ifp)->v_wait = (u_int16_t)EIGRP_HOLD_INTERVAL_DEFAULT; -  SET_IF_PARAM (IF_DEF_PARAMS (ifp), bandwidth); -  IF_DEF_PARAMS (ifp)->bandwidth = (u_int32_t) EIGRP_BANDWIDTH_DEFAULT; +	SET_IF_PARAM(IF_DEF_PARAMS(ifp), bandwidth); +	IF_DEF_PARAMS(ifp)->bandwidth = (u_int32_t)EIGRP_BANDWIDTH_DEFAULT; -  SET_IF_PARAM (IF_DEF_PARAMS (ifp), delay); -  IF_DEF_PARAMS (ifp)->delay = (u_int32_t) EIGRP_DELAY_DEFAULT; +	SET_IF_PARAM(IF_DEF_PARAMS(ifp), delay); +	IF_DEF_PARAMS(ifp)->delay = (u_int32_t)EIGRP_DELAY_DEFAULT; -  SET_IF_PARAM (IF_DEF_PARAMS (ifp), reliability); -  IF_DEF_PARAMS (ifp)->reliability = (u_char) EIGRP_RELIABILITY_DEFAULT; +	SET_IF_PARAM(IF_DEF_PARAMS(ifp), reliability); +	IF_DEF_PARAMS(ifp)->reliability = (u_char)EIGRP_RELIABILITY_DEFAULT; -  SET_IF_PARAM (IF_DEF_PARAMS (ifp), load); -  IF_DEF_PARAMS (ifp)->load = (u_char) EIGRP_LOAD_DEFAULT; +	SET_IF_PARAM(IF_DEF_PARAMS(ifp), load); +	IF_DEF_PARAMS(ifp)->load = (u_char)EIGRP_LOAD_DEFAULT; -  SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type); -  IF_DEF_PARAMS (ifp)->auth_type = EIGRP_AUTH_TYPE_NONE; +	SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type); +	IF_DEF_PARAMS(ifp)->auth_type = EIGRP_AUTH_TYPE_NONE; -  SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_keychain); -  IF_DEF_PARAMS (ifp)->auth_keychain= NULL; +	SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_keychain); +	IF_DEF_PARAMS(ifp)->auth_keychain = NULL; -  return rc; +	return rc;  } -struct eigrp_if_params * -eigrp_new_if_params (void) +struct eigrp_if_params *eigrp_new_if_params(void)  { -  struct eigrp_if_params *eip; - -  eip = XCALLOC (MTYPE_EIGRP_IF_PARAMS, sizeof (struct eigrp_if_params)); -  if (!eip) -    return NULL; - -  UNSET_IF_PARAM (eip, passive_interface); -  UNSET_IF_PARAM (eip, v_hello); -  UNSET_IF_PARAM (eip, v_wait); -  UNSET_IF_PARAM (eip, bandwidth); -  UNSET_IF_PARAM (eip, delay); -  UNSET_IF_PARAM (eip, reliability); -  UNSET_IF_PARAM (eip, load); -  UNSET_IF_PARAM (eip, auth_keychain); -  UNSET_IF_PARAM (eip, auth_type); - -  return eip; +	struct eigrp_if_params *eip; + +	eip = XCALLOC(MTYPE_EIGRP_IF_PARAMS, sizeof(struct eigrp_if_params)); +	if (!eip) +		return NULL; + +	UNSET_IF_PARAM(eip, passive_interface); +	UNSET_IF_PARAM(eip, v_hello); +	UNSET_IF_PARAM(eip, v_wait); +	UNSET_IF_PARAM(eip, bandwidth); +	UNSET_IF_PARAM(eip, delay); +	UNSET_IF_PARAM(eip, reliability); +	UNSET_IF_PARAM(eip, load); +	UNSET_IF_PARAM(eip, auth_keychain); +	UNSET_IF_PARAM(eip, auth_type); + +	return eip;  } -void -eigrp_del_if_params (struct eigrp_if_params *eip) +void eigrp_del_if_params(struct eigrp_if_params *eip)  { -  if(eip->auth_keychain) -    free(eip->auth_keychain); +	if (eip->auth_keychain) +		free(eip->auth_keychain); -  XFREE (MTYPE_EIGRP_IF_PARAMS, eip); +	XFREE(MTYPE_EIGRP_IF_PARAMS, eip);  } -struct eigrp_if_params * -eigrp_lookup_if_params (struct interface *ifp, struct in_addr addr) +struct eigrp_if_params *eigrp_lookup_if_params(struct interface *ifp, +					       struct in_addr addr)  { -  struct prefix_ipv4 p; -  struct route_node *rn; +	struct prefix_ipv4 p; +	struct route_node *rn; -  p.family = AF_INET; -  p.prefixlen = IPV4_MAX_PREFIXLEN; -  p.prefix = addr; +	p.family = AF_INET; +	p.prefixlen = IPV4_MAX_PREFIXLEN; +	p.prefix = addr; -  rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*) &p); +	rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p); -  if (rn) -    { -      route_unlock_node (rn); -      return rn->info; -    } +	if (rn) { +		route_unlock_node(rn); +		return rn->info; +	} -  return NULL; +	return NULL;  } -int -eigrp_if_up (struct eigrp_interface *ei) +int eigrp_if_up(struct eigrp_interface *ei)  { -  struct eigrp_prefix_entry *pe; -  struct eigrp_neighbor_entry *ne; -  struct eigrp_metrics metric; -  struct eigrp_interface *ei2; -  struct listnode *node, *nnode; -  struct eigrp *eigrp = eigrp_lookup (); - -  if (ei == NULL) -    return 0; - -  if (eigrp != NULL) -    eigrp_adjust_sndbuflen (eigrp, ei->ifp->mtu); -  else -    zlog_warn ("%s: eigrp_lookup () returned NULL", __func__); -  eigrp_if_stream_set (ei); - -  /* Set multicast memberships appropriately for new state. */ -  eigrp_if_set_multicast (ei); - -  thread_add_event(master, eigrp_hello_timer, ei, (1), NULL); - -  /*Prepare metrics*/ -  metric.bandwith = eigrp_bandwidth_to_scaled (EIGRP_IF_PARAM (ei,bandwidth)); -  metric.delay = eigrp_delay_to_scaled (EIGRP_IF_PARAM (ei,delay)); -  metric.load = EIGRP_IF_PARAM (ei,load); -  metric.reliability = EIGRP_IF_PARAM (ei,reliability); -  metric.mtu[0] = 0xDC; -  metric.mtu[1] = 0x05; -  metric.mtu[2] = 0x00; -  metric.hop_count = 0; -  metric.flags = 0; -  metric.tag = 0; - -  /*Add connected entry to topology table*/ - -  struct prefix_ipv4 dest_addr; - -  dest_addr.family = AF_INET; -  dest_addr.prefix = ei->connected->address->u.prefix4; -  dest_addr.prefixlen = ei->connected->address->prefixlen; -  apply_mask_ipv4 (&dest_addr); -  pe = eigrp_topology_table_lookup_ipv4 (eigrp->topology_table, &dest_addr); - -  if (pe == NULL) -    { -      pe = eigrp_prefix_entry_new (); -      pe->serno = eigrp->serno; -      pe->destination_ipv4 = prefix_ipv4_new (); -      prefix_copy ((struct prefix *)pe->destination_ipv4, -		   (struct prefix *)&dest_addr); -      pe->af = AF_INET; -      pe->nt = EIGRP_TOPOLOGY_TYPE_CONNECTED; - -      pe->state = EIGRP_FSM_STATE_PASSIVE; -      pe->fdistance = eigrp_calculate_metrics (eigrp, metric); -      pe->req_action |= EIGRP_FSM_NEED_UPDATE; -      eigrp_prefix_entry_add (eigrp->topology_table, pe); -      listnode_add(eigrp->topology_changes_internalIPV4, pe); -    } -  ne = eigrp_neighbor_entry_new (); -  ne->ei = ei; -  ne->reported_metric = metric; -  ne->total_metric = metric; -  ne->distance = eigrp_calculate_metrics (eigrp, metric); -  ne->reported_distance = 0; -  ne->prefix = pe; -  ne->adv_router = eigrp->neighbor_self; -  ne->flags = EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG; -  eigrp_neighbor_entry_add (pe, ne); - -  for (ALL_LIST_ELEMENTS (eigrp->eiflist, node, nnode, ei2)) -    { -      if (ei2->nbrs->count != 0) -        { -          eigrp_update_send (ei2); -        } -    } - -  pe->req_action &= ~EIGRP_FSM_NEED_UPDATE; -  listnode_delete(eigrp->topology_changes_internalIPV4, pe); - -  return 1; +	struct eigrp_prefix_entry *pe; +	struct eigrp_neighbor_entry *ne; +	struct eigrp_metrics metric; +	struct eigrp_interface *ei2; +	struct listnode *node, *nnode; +	struct eigrp *eigrp = eigrp_lookup(); + +	if (ei == NULL) +		return 0; + +	if (eigrp != NULL) +		eigrp_adjust_sndbuflen(eigrp, ei->ifp->mtu); +	else +		zlog_warn("%s: eigrp_lookup () returned NULL", __func__); +	eigrp_if_stream_set(ei); + +	/* Set multicast memberships appropriately for new state. */ +	eigrp_if_set_multicast(ei); + +	thread_add_event(master, eigrp_hello_timer, ei, (1), NULL); + +	/*Prepare metrics*/ +	metric.bandwith = +		eigrp_bandwidth_to_scaled(EIGRP_IF_PARAM(ei, bandwidth)); +	metric.delay = eigrp_delay_to_scaled(EIGRP_IF_PARAM(ei, delay)); +	metric.load = EIGRP_IF_PARAM(ei, load); +	metric.reliability = EIGRP_IF_PARAM(ei, reliability); +	metric.mtu[0] = 0xDC; +	metric.mtu[1] = 0x05; +	metric.mtu[2] = 0x00; +	metric.hop_count = 0; +	metric.flags = 0; +	metric.tag = 0; + +	/*Add connected entry to topology table*/ + +	struct prefix_ipv4 dest_addr; + +	dest_addr.family = AF_INET; +	dest_addr.prefix = ei->connected->address->u.prefix4; +	dest_addr.prefixlen = ei->connected->address->prefixlen; +	apply_mask_ipv4(&dest_addr); +	pe = eigrp_topology_table_lookup_ipv4(eigrp->topology_table, +					      &dest_addr); + +	if (pe == NULL) { +		pe = eigrp_prefix_entry_new(); +		pe->serno = eigrp->serno; +		pe->destination_ipv4 = prefix_ipv4_new(); +		prefix_copy((struct prefix *)pe->destination_ipv4, +			    (struct prefix *)&dest_addr); +		pe->af = AF_INET; +		pe->nt = EIGRP_TOPOLOGY_TYPE_CONNECTED; + +		pe->state = EIGRP_FSM_STATE_PASSIVE; +		pe->fdistance = eigrp_calculate_metrics(eigrp, metric); +		pe->req_action |= EIGRP_FSM_NEED_UPDATE; +		eigrp_prefix_entry_add(eigrp->topology_table, pe); +		listnode_add(eigrp->topology_changes_internalIPV4, pe); +	} +	ne = eigrp_neighbor_entry_new(); +	ne->ei = ei; +	ne->reported_metric = metric; +	ne->total_metric = metric; +	ne->distance = eigrp_calculate_metrics(eigrp, metric); +	ne->reported_distance = 0; +	ne->prefix = pe; +	ne->adv_router = eigrp->neighbor_self; +	ne->flags = EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG; +	eigrp_neighbor_entry_add(pe, ne); + +	for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) { +		if (ei2->nbrs->count != 0) { +			eigrp_update_send(ei2); +		} +	} + +	pe->req_action &= ~EIGRP_FSM_NEED_UPDATE; +	listnode_delete(eigrp->topology_changes_internalIPV4, pe); + +	return 1;  } -int -eigrp_if_down (struct eigrp_interface *ei) +int eigrp_if_down(struct eigrp_interface *ei)  { -  struct listnode *node, *nnode; -  struct eigrp_neighbor *nbr; +	struct listnode *node, *nnode; +	struct eigrp_neighbor *nbr; -  if (ei == NULL) -    return 0; +	if (ei == NULL) +		return 0; -  /* Shutdown packet reception and sending */ -  if(ei->t_hello) -    THREAD_OFF (ei->t_hello); +	/* Shutdown packet reception and sending */ +	if (ei->t_hello) +		THREAD_OFF(ei->t_hello); -  eigrp_if_stream_unset (ei); +	eigrp_if_stream_unset(ei); -  /*Set infinite metrics to routes learned by this interface and start query process*/ -  for (ALL_LIST_ELEMENTS (ei->nbrs, node, nnode, nbr)) -    { -      eigrp_nbr_delete(nbr); -    } +	/*Set infinite metrics to routes learned by this interface and start +	 * query process*/ +	for (ALL_LIST_ELEMENTS(ei->nbrs, node, nnode, nbr)) { +		eigrp_nbr_delete(nbr); +	} -  return 1; +	return 1;  } -void -eigrp_if_stream_set (struct eigrp_interface *ei) +void eigrp_if_stream_set(struct eigrp_interface *ei)  { -  /* set output fifo queue. */ -  if (ei->obuf == NULL) -    ei->obuf = eigrp_fifo_new (); +	/* set output fifo queue. */ +	if (ei->obuf == NULL) +		ei->obuf = eigrp_fifo_new();  } -void -eigrp_if_stream_unset (struct eigrp_interface *ei) +void eigrp_if_stream_unset(struct eigrp_interface *ei)  { -  struct eigrp *eigrp = ei->eigrp; - -  if (ei->obuf) -    { -      eigrp_fifo_free (ei->obuf); -      ei->obuf = NULL; - -      if (ei->on_write_q) -        { -          listnode_delete (eigrp->oi_write_q, ei); -          if (list_isempty (eigrp->oi_write_q)) -            thread_cancel (eigrp->t_write); -          ei->on_write_q = 0; -        } -    } +	struct eigrp *eigrp = ei->eigrp; + +	if (ei->obuf) { +		eigrp_fifo_free(ei->obuf); +		ei->obuf = NULL; + +		if (ei->on_write_q) { +			listnode_delete(eigrp->oi_write_q, ei); +			if (list_isempty(eigrp->oi_write_q)) +				thread_cancel(eigrp->t_write); +			ei->on_write_q = 0; +		} +	}  } -void -eigrp_if_set_multicast (struct eigrp_interface *ei) +void eigrp_if_set_multicast(struct eigrp_interface *ei)  { -  if ((EIGRP_IF_PASSIVE_STATUS (ei) == EIGRP_IF_ACTIVE)) -    { -      /* The interface should belong to the EIGRP-all-routers group. */ -      if (!EI_MEMBER_CHECK (ei, MEMBER_ALLROUTERS) -          && (eigrp_if_add_allspfrouters (ei->eigrp, ei->address, -                                          ei->ifp->ifindex) >= 0)) -        /* Set the flag only if the system call to join succeeded. */ -        EI_MEMBER_JOINED (ei, MEMBER_ALLROUTERS); -    } -  else -    { -      /* The interface should NOT belong to the EIGRP-all-routers group. */ -      if (EI_MEMBER_CHECK (ei, MEMBER_ALLROUTERS)) -        { -          /* Only actually drop if this is the last reference */ -          if (EI_MEMBER_COUNT (ei, MEMBER_ALLROUTERS) == 1) -            eigrp_if_drop_allspfrouters (ei->eigrp, ei->address, -                                         ei->ifp->ifindex); -          /* Unset the flag regardless of whether the system call to leave -             the group succeeded, since it's much safer to assume that -             we are not a member. */ -          EI_MEMBER_LEFT (ei, MEMBER_ALLROUTERS); -        } -    } +	if ((EIGRP_IF_PASSIVE_STATUS(ei) == EIGRP_IF_ACTIVE)) { +		/* The interface should belong to the EIGRP-all-routers group. +		 */ +		if (!EI_MEMBER_CHECK(ei, MEMBER_ALLROUTERS) +		    && (eigrp_if_add_allspfrouters(ei->eigrp, ei->address, +						   ei->ifp->ifindex) +			>= 0)) +			/* Set the flag only if the system call to join +			 * succeeded. */ +			EI_MEMBER_JOINED(ei, MEMBER_ALLROUTERS); +	} else { +		/* The interface should NOT belong to the EIGRP-all-routers +		 * group. */ +		if (EI_MEMBER_CHECK(ei, MEMBER_ALLROUTERS)) { +			/* Only actually drop if this is the last reference */ +			if (EI_MEMBER_COUNT(ei, MEMBER_ALLROUTERS) == 1) +				eigrp_if_drop_allspfrouters(ei->eigrp, +							    ei->address, +							    ei->ifp->ifindex); +			/* Unset the flag regardless of whether the system call +			   to leave +			   the group succeeded, since it's much safer to assume +			   that +			   we are not a member. */ +			EI_MEMBER_LEFT(ei, MEMBER_ALLROUTERS); +		} +	}  } -u_char -eigrp_default_iftype (struct interface *ifp) +u_char eigrp_default_iftype(struct interface *ifp)  { -  if (if_is_pointopoint (ifp)) -    return EIGRP_IFTYPE_POINTOPOINT; -  else if (if_is_loopback (ifp)) -    return EIGRP_IFTYPE_LOOPBACK; -  else -    return EIGRP_IFTYPE_BROADCAST; +	if (if_is_pointopoint(ifp)) +		return EIGRP_IFTYPE_POINTOPOINT; +	else if (if_is_loopback(ifp)) +		return EIGRP_IFTYPE_LOOPBACK; +	else +		return EIGRP_IFTYPE_BROADCAST;  } -void -eigrp_if_free (struct eigrp_interface *ei, int source) +void eigrp_if_free(struct eigrp_interface *ei, int source)  { -  struct prefix_ipv4 dest_addr; -  struct eigrp_prefix_entry *pe; -  struct eigrp *eigrp = eigrp_lookup (); - -  if (source == INTERFACE_DOWN_BY_VTY) -    { -      THREAD_OFF (ei->t_hello); -      eigrp_hello_send(ei,EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); -    } - -  dest_addr.family = AF_INET; -  dest_addr.prefix = ei->connected->address->u.prefix4; -  dest_addr.prefixlen = ei->connected->address->prefixlen; -  apply_mask_ipv4(&dest_addr); -  pe = eigrp_topology_table_lookup_ipv4 (eigrp->topology_table, &dest_addr); -  if (pe) -    eigrp_prefix_entry_delete (eigrp->topology_table, pe); - -  eigrp_if_down (ei); - -  list_delete (ei->nbrs); -  eigrp_delete_from_if (ei->ifp, ei); -  listnode_delete (ei->eigrp->eiflist, ei); - -  thread_cancel_event (master, ei); - -  memset (ei, 0, sizeof (*ei)); -  XFREE (MTYPE_EIGRP_IF, ei); +	struct prefix_ipv4 dest_addr; +	struct eigrp_prefix_entry *pe; +	struct eigrp *eigrp = eigrp_lookup(); + +	if (source == INTERFACE_DOWN_BY_VTY) { +		THREAD_OFF(ei->t_hello); +		eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); +	} + +	dest_addr.family = AF_INET; +	dest_addr.prefix = ei->connected->address->u.prefix4; +	dest_addr.prefixlen = ei->connected->address->prefixlen; +	apply_mask_ipv4(&dest_addr); +	pe = eigrp_topology_table_lookup_ipv4(eigrp->topology_table, +					      &dest_addr); +	if (pe) +		eigrp_prefix_entry_delete(eigrp->topology_table, pe); + +	eigrp_if_down(ei); + +	list_delete(ei->nbrs); +	eigrp_delete_from_if(ei->ifp, ei); +	listnode_delete(ei->eigrp->eiflist, ei); + +	thread_cancel_event(master, ei); + +	memset(ei, 0, sizeof(*ei)); +	XFREE(MTYPE_EIGRP_IF, ei);  } -static void -eigrp_delete_from_if (struct interface *ifp, struct eigrp_interface *ei) +static void eigrp_delete_from_if(struct interface *ifp, +				 struct eigrp_interface *ei)  { -  struct route_node *rn; -  struct prefix p; - -  p = *ei->address; -  p.prefixlen = IPV4_MAX_PREFIXLEN; - -  rn = route_node_lookup (IF_OIFS (ei->ifp), &p); -  assert (rn); -  assert (rn->info); -  rn->info = NULL; -  route_unlock_node (rn); -  route_unlock_node (rn); +	struct route_node *rn; +	struct prefix p; + +	p = *ei->address; +	p.prefixlen = IPV4_MAX_PREFIXLEN; + +	rn = route_node_lookup(IF_OIFS(ei->ifp), &p); +	assert(rn); +	assert(rn->info); +	rn->info = NULL; +	route_unlock_node(rn); +	route_unlock_node(rn);  }  /* Simulate down/up on the interface.  This is needed, for example, when     the MTU changes. */ -void -eigrp_if_reset (struct interface *ifp) +void eigrp_if_reset(struct interface *ifp)  { -  struct route_node *rn; +	struct route_node *rn; -  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) -    { -      struct eigrp_interface *ei; +	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { +		struct eigrp_interface *ei; -      if ((ei = rn->info) == NULL) -        continue; +		if ((ei = rn->info) == NULL) +			continue; -      eigrp_if_down (ei); -      eigrp_if_up (ei); -    } +		eigrp_if_down(ei); +		eigrp_if_up(ei); +	}  } -struct eigrp_interface * -eigrp_if_lookup_by_local_addr (struct eigrp *eigrp, struct interface *ifp, -                               struct in_addr address) +struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *eigrp, +						      struct interface *ifp, +						      struct in_addr address)  { -  struct listnode *node; -  struct eigrp_interface *ei; +	struct listnode *node; +	struct eigrp_interface *ei; -  for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei)) -    { -      if (ifp && ei->ifp != ifp) -        continue; +	for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { +		if (ifp && ei->ifp != ifp) +			continue; -      if (IPV4_ADDR_SAME (&address, &ei->address->u.prefix4)) -        return ei; -    } +		if (IPV4_ADDR_SAME(&address, &ei->address->u.prefix4)) +			return ei; +	} -  return NULL; +	return NULL;  }  /** @@ -531,92 +509,84 @@ eigrp_if_lookup_by_local_addr (struct eigrp *eigrp, struct interface *ifp,   * @par   * Function is used for lookup interface by name.   */ -struct eigrp_interface * -eigrp_if_lookup_by_name (struct eigrp *eigrp, const char *if_name) +struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp, +						const char *if_name)  { -  struct eigrp_interface *ei; -  struct listnode *node; - -  /* iterate over all eigrp interfaces */ -  for (ALL_LIST_ELEMENTS_RO (eigrp->eiflist, node, ei)) -    { -      /* compare int name with eigrp interface's name */ -      if(strcmp(ei->ifp->name, if_name) == 0) -        { -          return ei; -        } -    } - -  return NULL; +	struct eigrp_interface *ei; +	struct listnode *node; + +	/* iterate over all eigrp interfaces */ +	for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { +		/* compare int name with eigrp interface's name */ +		if (strcmp(ei->ifp->name, if_name) == 0) { +			return ei; +		} +	} + +	return NULL;  }  /* determine receiving interface by ifp and source address */ -struct eigrp_interface * -eigrp_if_lookup_recv_if (struct eigrp *eigrp, struct in_addr src, -                         struct interface *ifp) +struct eigrp_interface *eigrp_if_lookup_recv_if(struct eigrp *eigrp, +						struct in_addr src, +						struct interface *ifp)  { -  struct route_node *rn; -  struct prefix_ipv4 addr; -  struct eigrp_interface *ei, *match; +	struct route_node *rn; +	struct prefix_ipv4 addr; +	struct eigrp_interface *ei, *match; -  addr.family = AF_INET; -  addr.prefix = src; -  addr.prefixlen = IPV4_MAX_BITLEN; +	addr.family = AF_INET; +	addr.prefix = src; +	addr.prefixlen = IPV4_MAX_BITLEN; -  match = NULL; +	match = NULL; -  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) -    { -      ei = rn->info; +	for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { +		ei = rn->info; -      if (!ei) /* oi can be NULL for PtP aliases */ -        continue; +		if (!ei) /* oi can be NULL for PtP aliases */ +			continue; -      if (if_is_loopback (ei->ifp)) -        continue; +		if (if_is_loopback(ei->ifp)) +			continue; -      if (prefix_match (CONNECTED_PREFIX (ei->connected), -                        (struct prefix *) &addr)) -        { -          if ((match == NULL) -              || (match->address->prefixlen < ei->address->prefixlen)) -            match = ei; -        } -    } +		if (prefix_match(CONNECTED_PREFIX(ei->connected), +				 (struct prefix *)&addr)) { +			if ((match == NULL) || (match->address->prefixlen +						< ei->address->prefixlen)) +				match = ei; +		} +	} -  return match; +	return match;  } -u_int32_t -eigrp_bandwidth_to_scaled (u_int32_t bandwidth) +u_int32_t eigrp_bandwidth_to_scaled(u_int32_t bandwidth)  { -  uint64_t temp_bandwidth = (256ull * 10000000) / bandwidth; +	uint64_t temp_bandwidth = (256ull * 10000000) / bandwidth; -  temp_bandwidth = -    temp_bandwidth < EIGRP_MAX_METRIC ? temp_bandwidth : EIGRP_MAX_METRIC; +	temp_bandwidth = temp_bandwidth < EIGRP_MAX_METRIC ? temp_bandwidth +							   : EIGRP_MAX_METRIC; -  return (u_int32_t) temp_bandwidth; +	return (u_int32_t)temp_bandwidth;  } -u_int32_t -eigrp_scaled_to_bandwidth (u_int32_t scaled) +u_int32_t eigrp_scaled_to_bandwidth(u_int32_t scaled)  { -  uint64_t temp_scaled = scaled * (256ull * 10000000); +	uint64_t temp_scaled = scaled * (256ull * 10000000); -  temp_scaled = -    temp_scaled < EIGRP_MAX_METRIC ? temp_scaled : EIGRP_MAX_METRIC; +	temp_scaled = +		temp_scaled < EIGRP_MAX_METRIC ? temp_scaled : EIGRP_MAX_METRIC; -  return (u_int32_t) temp_scaled; +	return (u_int32_t)temp_scaled;  } -u_int32_t -eigrp_delay_to_scaled (u_int32_t delay) +u_int32_t eigrp_delay_to_scaled(u_int32_t delay)  { -  return delay * 256; +	return delay * 256;  } -u_int32_t -eigrp_scaled_to_delay (u_int32_t scaled) +u_int32_t eigrp_scaled_to_delay(u_int32_t scaled)  { -  return scaled / 256; +	return scaled / 256;  }  | 
