Exemplo n.º 1
0
/* Utility function of convert between struct prefix <=> union sockunion.
 * FIXME This function isn't used anywhere. */
struct prefix *
sockunion2prefix (const union sockunion *dest,
		  const union sockunion *mask)
{
  if (dest->sa.sa_family == AF_INET)
    {
      struct prefix_ipv4 *p;

      p = prefix_ipv4_new ();
      p->family = AF_INET;
      p->prefix = dest->sin.sin_addr;
      p->prefixlen = ip_masklen (mask->sin.sin_addr);
      return (struct prefix *) p;
    }
#ifdef HAVE_IPV6
  if (dest->sa.sa_family == AF_INET6)
    {
      struct prefix_ipv6 *p;

      p = prefix_ipv6_new ();
      p->family = AF_INET6;
      p->prefixlen = ip6_masklen (mask->sin6.sin6_addr);
      memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
      return (struct prefix *) p;
    }
#endif /* HAVE_IPV6 */
  return NULL;
}
Exemplo n.º 2
0
/* Utility function of convert between struct prefix <=> union sockunion. */
struct prefix *
sockunion2hostprefix (const union sockunion *su)
{
  if (su->sa.sa_family == AF_INET)
    {
      struct prefix_ipv4 *p;

      p = prefix_ipv4_new ();
      p->family = AF_INET;
      p->prefix = su->sin.sin_addr;
      p->prefixlen = IPV4_MAX_BITLEN;
      return (struct prefix *) p;
    }
#ifdef HAVE_IPV6
  if (su->sa.sa_family == AF_INET6)
    {
      struct prefix_ipv6 *p;

      p = prefix_ipv6_new ();
      p->family = AF_INET6;
      p->prefixlen = IPV6_MAX_BITLEN;
      memcpy (&p->prefix, &su->sin6.sin6_addr, sizeof (struct in6_addr));
      return (struct prefix *) p;
    }
#endif /* HAVE_IPV6 */
  return NULL;
}
Exemplo n.º 3
0
int recv_routes_reply(struct ctrl_client * ctrl_client, struct rfpbuf * buffer)
{
  const struct rfp_ipv4_route * rir = buffer->data;
  struct route_ipv4 * route = new_route();
 
  route->p = prefix_ipv4_new();
  route->p->family = AF_INET;
  memcpy(&route->p->prefix, &rir->p, 4);
  route->p->prefixlen = ntohs(rir->prefixlen);

  // print route
  if(IS_OSPF6_SIBLING_DEBUG_MSG)
  {
    char prefix_str[INET_ADDRSTRLEN];
    if (inet_ntop(AF_INET, &(route->p->prefix.s_addr), prefix_str, INET_ADDRSTRLEN) != 1)
      zlog_debug("%s/%d", prefix_str, route->p->prefixlen);
  }
  return 0;
}
Exemplo n.º 4
0
void
isis_circuit_add_addr (struct isis_circuit *circuit,
		       struct connected *connected)
{
  struct listnode *node;
  struct prefix_ipv4 *ipv4;
  u_char buf[BUFSIZ];
#ifdef HAVE_IPV6
  struct prefix_ipv6 *ipv6;
#endif /* HAVE_IPV6 */

  memset (&buf, 0, BUFSIZ);
  if (connected->address->family == AF_INET)
    {
      u_int32_t addr = connected->address->u.prefix4.s_addr;
      addr = ntohl (addr);
      if (IPV4_NET0(addr) ||
          IPV4_NET127(addr) ||
          IN_CLASSD(addr) ||
          IPV4_LINKLOCAL(addr))
        return;

      for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ipv4))
        if (prefix_same ((struct prefix *) ipv4, connected->address))
          return;

      ipv4 = prefix_ipv4_new ();
      ipv4->prefixlen = connected->address->prefixlen;
      ipv4->prefix = connected->address->u.prefix4;
      listnode_add (circuit->ip_addrs, ipv4);

      /* Update MPLS TE Local IP address parameter */
      set_circuitparams_local_ipaddr (circuit->mtc, ipv4->prefix);

      if (circuit->area)
        lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);

#ifdef EXTREME_DEBUG
      prefix2str (connected->address, buf, BUFSIZ);
      zlog_debug ("Added IP address %s to circuit %d", buf,
		 circuit->circuit_id);
#endif /* EXTREME_DEBUG */
    }
Exemplo n.º 5
0
/*
 * EIGRP UPDATE read function
 */
void
eigrp_update_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
                      struct stream * s, struct eigrp_interface *ei, int size)
{
  struct eigrp_neighbor *nbr;
  struct TLV_IPv4_Internal_type *tlv;
  struct eigrp_prefix_entry *pe;
  struct eigrp_neighbor_entry *ne;
  u_int32_t flags;
  u_int16_t type;
  uint16_t  length;
  u_char same;
  struct access_list *alist;
  struct prefix_list *plist;
  struct eigrp *e;
  u_char graceful_restart;
  u_char graceful_restart_final;
  struct list *nbr_prefixes;
  int ret;

  /* increment statistics. */
  ei->update_in++;

  /* get neighbor struct */
  nbr = eigrp_nbr_get(ei, eigrph, iph);

  /* neighbor must be valid, eigrp_nbr_get creates if none existed */
  assert(nbr);

  flags = ntohl(eigrph->flags);

  if (flags & EIGRP_CR_FLAG)
    {
      return;
    }

  same = 0;
  graceful_restart = 0;
  graceful_restart_final = 0;
  if((nbr->recv_sequence_number) == (ntohl(eigrph->sequence)))
      same = 1;

  nbr->recv_sequence_number = ntohl(eigrph->sequence);
  if (IS_DEBUG_EIGRP_PACKET(0, RECV))
    zlog_debug("Processing Update size[%u] int(%s) nbr(%s) seq [%u] flags [%0x]",
               size, ifindex2ifname(nbr->ei->ifp->ifindex),
               inet_ntoa(nbr->src),
               nbr->recv_sequence_number, flags);


    if((flags == (EIGRP_INIT_FLAG+EIGRP_RS_FLAG+EIGRP_EOT_FLAG)) && (!same))
    {
    	/* Graceful restart Update received with all routes */

		zlog_info("Neighbor %s (%s) is resync: peer graceful-restart",
				  inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex));

		/* get all prefixes from neighbor from topology table */
    	nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr);
    	graceful_restart = 1;
    	graceful_restart_final = 1;
    }
    else if((flags == (EIGRP_INIT_FLAG+EIGRP_RS_FLAG)) && (!same))
    {
    	/* Graceful restart Update received, routes also in next packet */

		zlog_info("Neighbor %s (%s) is resync: peer graceful-restart",
				  inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex));

		/* get all prefixes from neighbor from topology table */
    	nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr);
    	/* save prefixes to neighbor for later use */
    	nbr->nbr_gr_prefixes = nbr_prefixes;
    	graceful_restart = 1;
    	graceful_restart_final = 0;
    }
    else if((flags == (EIGRP_EOT_FLAG)) && (!same))
	{
		/* If there was INIT+RS Update packet before,
		 *  consider this as GR EOT */

		if(nbr->nbr_gr_prefixes != NULL)
		{
			/* this is final packet of GR */
			nbr_prefixes = nbr->nbr_gr_prefixes;
			nbr->nbr_gr_prefixes = NULL;

			graceful_restart = 1;
			graceful_restart_final = 1;
		}

	}
    else if((flags == (0)) && (!same))
	{
		/* If there was INIT+RS Update packet before,
		 *  consider this as GR not final packet */

		if(nbr->nbr_gr_prefixes != NULL)
		{
			/* this is GR not final route packet */
			nbr_prefixes = nbr->nbr_gr_prefixes;

			graceful_restart = 1;
			graceful_restart_final = 0;
		}

	}
    else if((flags & EIGRP_INIT_FLAG) && (!same))
    {   /* When in pending state, send INIT update only if it wasn't
        already sent before (only if init_sequence is 0) */
        if((nbr->state == EIGRP_NEIGHBOR_PENDING) && (nbr->init_sequence_number == 0))
          eigrp_update_send_init(nbr);

        if (nbr->state == EIGRP_NEIGHBOR_UP)
          {
            eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN);
            eigrp_topology_neighbor_down(nbr->ei->eigrp,nbr);
            nbr->recv_sequence_number = ntohl(eigrph->sequence);
            zlog_info("Neighbor %s (%s) is down: peer restarted",
                      inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex));
            eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING);
            zlog_info("Neighbor %s (%s) is pending: new adjacency",
                      inet_ntoa(nbr->src), ifindex2ifname(nbr->ei->ifp->ifindex));
            eigrp_update_send_init(nbr);
          }
    }

  /*If there is topology information*/
  while (s->endp > s->getp)
    {
      type = stream_getw(s);
      if (type == EIGRP_TLV_IPv4_INT)
        {
          stream_set_getp(s, s->getp - sizeof(u_int16_t));

          tlv = eigrp_read_ipv4_tlv(s);

          /*searching if destination exists */
          struct prefix_ipv4 *dest_addr;
          dest_addr = prefix_ipv4_new();
          dest_addr->prefix = tlv->destination;
          dest_addr->prefixlen = tlv->prefix_length;
          struct eigrp_prefix_entry *dest = eigrp_topology_table_lookup_ipv4(
              eigrp->topology_table, dest_addr);

          /*if exists it comes to DUAL*/
          if (dest != NULL)
            {
        	  /* remove received prefix from neighbor prefix list if in GR */
        	  if(graceful_restart)
        		  remove_received_prefix_gr(nbr_prefixes, dest);

              struct eigrp_fsm_action_message *msg;
              msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
                  sizeof(struct eigrp_fsm_action_message));
              struct eigrp_neighbor_entry *entry =
                  eigrp_prefix_entry_lookup(dest->entries, nbr);

              msg->packet_type = EIGRP_OPC_UPDATE;
              msg->eigrp = eigrp;
              msg->data_type = EIGRP_TLV_IPv4_INT;
              msg->adv_router = nbr;
              msg->data.ipv4_int_type = tlv;
              msg->entry = entry;
              msg->prefix = dest;
              int event = eigrp_get_fsm_event(msg);
              eigrp_fsm_event(msg, event);
            }
          else
            {
              /*Here comes topology information save*/
              pe = eigrp_prefix_entry_new();
              pe->serno = eigrp->serno;
              pe->destination_ipv4 = dest_addr;
              pe->af = AF_INET;
              pe->state = EIGRP_FSM_STATE_PASSIVE;
              pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE;

              ne = eigrp_neighbor_entry_new();
              ne->ei = ei;
              ne->adv_router = nbr;
              ne->reported_metric = tlv->metric;
              ne->reported_distance = eigrp_calculate_metrics(eigrp,
                  &tlv->metric);

              //TODO: Work in progress
              /*
               * Filtering
               */
        	  e = eigrp_lookup();
        	  /* get access-list from eigrp process */
        	  alist = e->list[EIGRP_FILTER_IN];
			  zlog_info("PROC IN Prefix: %s", inet_ntoa(dest_addr->prefix));
			  if (alist) {
				  zlog_info ("ALIST PROC IN: %s", alist->name);
			  } else {
				  zlog_info("ALIST PROC IN je prazdny");
			  }

			  /* Check if access-list fits */
			  if (alist && access_list_apply (alist,
						 (struct prefix *) dest_addr) == FILTER_DENY)
			  {
				  /* If yes, set reported metric to Max */
				  zlog_info("PROC alist IN: Skipping");
				  //ne->reported_metric.delay = EIGRP_MAX_METRIC;
				  zlog_info("PROC IN Prefix: %s", inet_ntoa(dest_addr->prefix));
				  eigrp_IPv4_InternalTLV_free (tlv);
				  continue;
			  } else {
				  zlog_info("PROC alist IN: NENastavujem metriku ");
			  }

			  plist = e->prefix[EIGRP_FILTER_IN];

			  if (plist) {
				  zlog_info ("PLIST PROC IN: %s", plist->name);
			  } else {
				  zlog_info("PLIST PROC IN je prazdny");
			  }

			  /* Check if prefix-list fits */
			  if (plist && prefix_list_apply (plist,
						 (struct prefix *) dest_addr) == FILTER_DENY)
			  {
				  /* If yes, set reported metric to Max */
				  zlog_info("PLIST PROC IN: Skipping");
				  //ne->reported_metric.delay = EIGRP_MAX_METRIC;
				  zlog_info("PLIST PROC IN Prefix: %s", inet_ntoa(dest_addr->prefix));
				  eigrp_IPv4_InternalTLV_free (tlv);
				  continue;
			  } else {
				  zlog_info("PLIST PROC IN: NENastavujem metriku ");
			  }

			  //Check route-map

			  /*if (e->routemap[EIGRP_FILTER_IN])
			  {
			  	 ret = route_map_apply (e->routemap[EIGRP_FILTER_IN],
			  				   (struct prefix *)dest_addr, RMAP_EIGRP, NULL);

			  	 if (ret == RMAP_DENYMATCH)
			  	 {
			  	    zlog_debug ("%s is filtered by route-map",inet_ntoa (dest_addr->prefix));
			  	    continue;
			  	 }
			  }*/

			  /*Get access-list from current interface */
			  zlog_info("Checking access_list on interface: %s",ei->ifp->name);
			  alist = ei->list[EIGRP_FILTER_IN];
			  if (alist) {
			  	  zlog_info ("ALIST INT IN: %s", alist->name);
			  } else {
			  	  zlog_info("ALIST INT IN je prazdny");
			  	}

			  /* Check if access-list fits */
			  if (alist && access_list_apply (alist, (struct prefix *) dest_addr) == FILTER_DENY)
			  {
				  /* If yes, set reported metric to Max */
			  	  zlog_info("INT alist IN: Skipping");
			  	  //ne->reported_metric.delay = EIGRP_MAX_METRIC;
			  	  zlog_info("INT IN Prefix: %s", inet_ntoa(dest_addr->prefix));
			  	  eigrp_IPv4_InternalTLV_free (tlv);
			  	  continue;
			  	} else {
			  	  zlog_info("INT IN: NENastavujem metriku ");
			  }

			  plist = ei->prefix[EIGRP_FILTER_IN];

			  if (plist) {
				  zlog_info ("PLIST INT IN: %s", plist->name);
			  } else {
				  zlog_info("PLIST INT IN je prazdny");
			  }

			  /* Check if prefix-list fits */
			  if (plist && prefix_list_apply (plist,
						 (struct prefix *) dest_addr) == FILTER_DENY)
			  {
				  /* If yes, set reported metric to Max */
				  zlog_info("PLIST INT IN: Skipping");
				  //ne->reported_metric.delay = EIGRP_MAX_METRIC;
				  zlog_info("PLIST INT IN Prefix: %s", inet_ntoa(dest_addr->prefix));
				  eigrp_IPv4_InternalTLV_free (tlv);
				  continue;
			  } else {
				  zlog_info("PLIST INT IN: NENastavujem metriku ");
			  }

			  //Check route-map

			  /*if (ei->routemap[EIGRP_FILTER_IN])
			  {
				 ret = route_map_apply (ei->routemap[EIGRP_FILTER_IN],
							   (struct prefix *)dest_addr, RMAP_EIGRP, NULL);

				 if (ret == RMAP_DENYMATCH)
				 {
					zlog_debug ("%s is filtered by route-map",inet_ntoa (dest_addr->prefix));
					continue;
				 }
			  }*/
			  /*
			   * End of filtering
			   */

			  ne->distance = eigrp_calculate_total_metrics(eigrp, ne);

			  zlog_info("<DEBUG PROC IN Distance: %x", ne->distance);
			  zlog_info("<DEBUG PROC IN Delay: %x", ne->total_metric.delay);

              pe->fdistance = pe->distance = pe->rdistance =
                  ne->distance;
              ne->prefix = pe;
              ne->flags = EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG;

              eigrp_prefix_entry_add(eigrp->topology_table, pe);
              eigrp_neighbor_entry_add(pe, ne);
              pe->distance = pe->fdistance = pe->rdistance = ne->distance;
              pe->reported_metric = ne->total_metric;
              eigrp_topology_update_node_flags(pe);

              pe->req_action |= EIGRP_FSM_NEED_UPDATE;
              listnode_add(eigrp->topology_changes_internalIPV4, pe);
            }
          eigrp_IPv4_InternalTLV_free (tlv);
        }
    }

    /* ask about prefixes not present in GR update,
     * if this is final GR packet */
    if(graceful_restart_final)
    {
    	eigrp_update_receive_GR_ask(eigrp, nbr, nbr_prefixes);
    }

  /*
   * We don't need to send separate Ack for INIT Update. INIT will be acked in EOT Update.
   */
  if ((nbr->state == EIGRP_NEIGHBOR_UP) && !(flags == EIGRP_INIT_FLAG))
    {
      eigrp_hello_send_ack(nbr);
    }

  eigrp_query_send_all(eigrp);
  eigrp_update_send_all(eigrp, ei);
}
Exemplo n.º 6
0
/* Add connected IPv4 route to the interface. */
void
connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
		   u_char prefixlen, struct in_addr *broad, const char *label)
{
	struct prefix_ipv4 *p;
	struct connected *ifc;

	/* Make connected structure. */
	ifc = connected_new();
	ifc->ifp = ifp;
	ifc->flags = flags;
	/* If we get a notification from the kernel,
	 * we can safely assume the address is known to the kernel */
	SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);

	/* Allocate new connected address. */
	p = prefix_ipv4_new();
	p->family = AF_INET;
	p->prefix = *addr;
	p->prefixlen = prefixlen;
	ifc->address = (struct prefix *)p;

	/* If there is broadcast or peer address. */
	if (broad) {
		p = prefix_ipv4_new();
		p->family = AF_INET;
		p->prefix = *broad;
		p->prefixlen = prefixlen;
		ifc->destination = (struct prefix *)p;

		/* validate the destination address */
		if (CONNECTED_PEER(ifc)) {
			if (IPV4_ADDR_SAME(addr, broad))
				zlog_warn
				    ("warning: interface %s has same local and peer "
				     "address %s, routing protocols may malfunction",
				     ifp->name, inet_ntoa(*addr));
		} else {
			if (broad->s_addr !=
			    ipv4_broadcast_addr(addr->s_addr, prefixlen)) {
				char buf[2][INET_ADDRSTRLEN];
				struct in_addr bcalc;
				bcalc.s_addr =
				    ipv4_broadcast_addr(addr->s_addr,
							prefixlen);
				zlog_warn
				    ("warning: interface %s broadcast addr %s/%d != "
				     "calculated %s, routing protocols may malfunction",
				     ifp->name, inet_ntop(AF_INET, broad,
							  buf[0],
							  sizeof(buf[0])),
				     prefixlen, inet_ntop(AF_INET, &bcalc,
							  buf[1],
							  sizeof(buf[1])));
			}
		}

	} else {
		if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
			zlog_warn("warning: %s called for interface %s "
				  "with peer flag set, but no peer address supplied",
				  __func__, ifp->name);
			UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
		}

		/* no broadcast or destination address was supplied */
		if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp))
			zlog_warn
			    ("warning: PtP interface %s with addr %s/%d needs a "
			     "peer address", ifp->name, inet_ntoa(*addr),
			     prefixlen);
	}

	/* Label of this address. */
	if (label)
		ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);

	/* For all that I know an IPv4 address is always ready when we receive
	 * the notification. So it should be safe to set the REAL flag here. */
	SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);

	connected_update(ifp, ifc);
}
Exemplo n.º 7
0
struct ospf_interface * 
ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data)
{
  struct ospf_interface * voi;
  struct interface * vi;
  char   ifname[INTERFACE_NAMSIZ + 1];
  struct ospf_area *area;
  struct in_addr area_id;
  struct connected *co;
  struct prefix_ipv4 *p;
  
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): Start");
  if (vlink_count == OSPF_VL_MAX_COUNT)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_vl_new(): Alarm: "
		   "cannot create more than OSPF_MAX_VL_COUNT virtual links");
      return NULL;
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): creating pseudo zebra interface");

  snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count);
  vi = if_create (ifname, strnlen(ifname, sizeof(ifname)));
  co = connected_new ();
  co->ifp = vi;
  listnode_add (vi->connected, co);

  p = prefix_ipv4_new ();
  p->family = AF_INET;
  p->prefix.s_addr = 0;
  p->prefixlen = 0;
 
  co->address = (struct prefix *)p;
  
  voi = ospf_if_new (ospf, vi, co->address);
  if (voi == NULL)
    {
      if (IS_DEBUG_OSPF_EVENT)
	zlog_debug ("ospf_vl_new(): Alarm: OSPF int structure is not created");
      return NULL;
    }
  voi->connected = co;
  voi->vl_data = vl_data;
  voi->ifp->mtu = OSPF_VL_MTU;
  voi->type = OSPF_IFTYPE_VIRTUALLINK;

  vlink_count++;
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): Created name: %s", ifname);
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): set if->name to %s", vi->name);

  area_id.s_addr = 0;
  area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
  voi->area = area;

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): set associated area to the backbone");

  ospf_nbr_add_self (voi);
  ospf_area_add_if (voi->area, voi);

  ospf_if_stream_set (voi);

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("ospf_vl_new(): Stop");
  return voi;
}
Exemplo n.º 8
0
/*EIGRP QUERY read function*/
void
eigrp_query_receive (struct eigrp *eigrp, struct ip *iph, struct eigrp_header *eigrph,
                     struct stream * s, struct eigrp_interface *ei, int size)
{
  struct eigrp_neighbor *nbr;
  struct TLV_IPv4_Internal_type *tlv;
  struct eigrp_prefix_entry *temp_tn;
  struct eigrp_neighbor_entry *temp_te;

  u_int16_t type;

  /* increment statistics. */
  ei->query_in++;

  /* get neighbor struct */
  nbr = eigrp_nbr_get(ei, eigrph, iph);

  /* neighbor must be valid, eigrp_nbr_get creates if none existed */
  assert(nbr);

  nbr->recv_sequence_number = ntohl(eigrph->sequence);

  while (s->endp > s->getp)
    {
      type = stream_getw(s);
      if (type == EIGRP_TLV_IPv4_INT)
        {
          stream_set_getp(s, s->getp - sizeof(u_int16_t));

          tlv = eigrp_read_ipv4_tlv(s);

          struct prefix_ipv4 *dest_addr;
          dest_addr = prefix_ipv4_new();
          dest_addr->prefix = tlv->destination;
          dest_addr->prefixlen = tlv->prefix_length;
          struct eigrp_prefix_entry *dest = eigrp_topology_table_lookup_ipv4(
              eigrp->topology_table, dest_addr);

          /* If the destination exists (it should, but one never know)*/
          if (dest != NULL)
            {
              struct eigrp_fsm_action_message *msg;
              msg = XCALLOC(MTYPE_EIGRP_FSM_MSG,
                  sizeof(struct eigrp_fsm_action_message));
              struct eigrp_neighbor_entry *entry = eigrp_prefix_entry_lookup(
                  dest->entries, nbr);
              msg->packet_type = EIGRP_OPC_QUERY;
              msg->eigrp = eigrp;
              msg->data_type = EIGRP_TLV_IPv4_INT;
              msg->adv_router = nbr;
              msg->data.ipv4_int_type = tlv;
              msg->entry = entry;
              msg->prefix = dest;
              int event = eigrp_get_fsm_event(msg);
              eigrp_fsm_event(msg, event);
            }
          eigrp_IPv4_InternalTLV_free (tlv);
        }
    }
  eigrp_hello_send_ack(nbr);
  eigrp_query_send_all(eigrp);
  eigrp_update_send_all(eigrp,nbr->ei);
}
Exemplo n.º 9
0
/* Add connected IPv4 route to the interface. */
void
connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, 
		    u_char prefixlen, struct in_addr *broad, 
		    const char *label)
{
  struct prefix_ipv4 *p;
  struct connected *ifc;

  /* Make connected structure. */
  ifc = connected_new ();
  ifc->ifp = ifp;
  ifc->flags = flags;

  /* Allocate new connected address. */
  p = prefix_ipv4_new ();
  p->family = AF_INET;
  p->prefix = *addr;
  p->prefixlen = prefixlen;
  ifc->address = (struct prefix *) p;
  
  /* If there is broadcast or peer address. */
  if (broad)
    {
      p = prefix_ipv4_new ();
      p->family = AF_INET;
      p->prefix = *broad;
      p->prefixlen = prefixlen;
      ifc->destination = (struct prefix *) p;

      /* validate the destination address */
      if (CONNECTED_PEER(ifc))
        {
	  if (IPV4_ADDR_SAME(addr,broad))
	    zlog_warn("warning: interface %s has same local and peer "
		      "address %s, routing protocols may malfunction",
		      ifp->name,inet_ntoa(*addr));
        }
      else
        {
	  if (broad->s_addr != ipv4_broadcast_addr(addr->s_addr,prefixlen))
	    {
	      char buf[2][INET_ADDRSTRLEN];
	      struct in_addr bcalc;
	      bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,prefixlen);
	      zlog_warn("warning: interface %s broadcast addr %s/%d != "
	       		"calculated %s, routing protocols may malfunction",
	    		ifp->name,
			inet_ntop (AF_INET, broad, buf[0], sizeof(buf[0])),
			prefixlen,
			inet_ntop (AF_INET, &bcalc, buf[1], sizeof(buf[1])));
	    }
        }

    }
  else
    {
      if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
        {
	  zlog_warn("warning: %s called for interface %s "
		    "with peer flag set, but no peer address supplied",
		    __func__, ifp->name);
	  UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
	}

      /* no broadcast or destination address was supplied */
      if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp))
	zlog_warn("warning: PtP interface %s with addr %s/%d needs a "
		  "peer address",ifp->name,inet_ntoa(*addr),prefixlen);
    }

  /* Label of this address. */
  if (label)
    ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);

  /* nothing to do? */
  if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL)
    return;
  
  connected_announce (ifp, ifc);
}
Exemplo n.º 10
0
/* Add connected IPv4 route to the interface. */
void
connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, 
		    u_char prefixlen, struct in_addr *broad, 
		    const char *label)
{
  struct prefix_ipv4 *p;
  struct connected *ifc;

  /* Make connected structure. */
  ifc = connected_new ();
  ifc->ifp = ifp;
  ifc->flags = flags;

  /* Allocate new connected address. */
  p = prefix_ipv4_new ();
  p->family = AF_INET;
  p->prefix = *addr;
  p->prefixlen = prefixlen;
  ifc->address = (struct prefix *) p;
  
  /* If there is broadcast or pointopoint address. */
  if (broad)
    {
      p = prefix_ipv4_new ();
      p->family = AF_INET;
      p->prefix = *broad;
      ifc->destination = (struct prefix *) p;

      /* validate the destination address */
      if (ifp->flags & IFF_POINTOPOINT)
        {
	  if (IPV4_ADDR_SAME(addr,broad))
	    zlog_warn("warning: PtP interface %s has same local and peer "
		      "address %s, routing protocols may malfunction",
		      ifp->name,inet_ntoa(*addr));
	  else if ((prefixlen != IPV4_MAX_PREFIXLEN) &&
	   	   (ipv4_network_addr(addr->s_addr,prefixlen) !=
	   	    ipv4_network_addr(broad->s_addr,prefixlen)))
	    {
	      char buf[2][INET_ADDRSTRLEN];
	      zlog_warn("warning: PtP interface %s network mismatch: local "
	      		"%s/%d vs. peer %s, routing protocols may malfunction",
	    		ifp->name,
			inet_ntop (AF_INET, addr, buf[0], sizeof(buf[0])),
			prefixlen,
			inet_ntop (AF_INET, broad, buf[1], sizeof(buf[1])));
	    }
        }
      else
        {
	  if (broad->s_addr != ipv4_broadcast_addr(addr->s_addr,prefixlen))
	    {
	      char buf[2][INET_ADDRSTRLEN];
	      struct in_addr bcalc;
	      bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,prefixlen);
	      zlog_warn("warning: interface %s broadcast addr %s/%d != "
	       		"calculated %s, routing protocols may malfunction",
	    		ifp->name,
			inet_ntop (AF_INET, broad, buf[0], sizeof(buf[0])),
			prefixlen,
			inet_ntop (AF_INET, &bcalc, buf[1], sizeof(buf[1])));
	    }
	  /*gjd : for Rtsuit restart , ip address write show running.*/
	  if(!CHECK_FLAG(ifc->ip_config,RTMD_RESTART_IP_CONFIG)&&(keep_kernel_mode == 1))
	  	{
	  		SET_FLAG(ifc->ip_config,RTMD_RESTART_IP_CONFIG);			
			/*zlog_err("%s : line %d ifc->conf(%u), ifc->ipconfig(%u).\n",
				__func__,__LINE__,ifc->conf,ifc->ip_config);*/
	  	}
      }

    }
  else
    /* no broadcast or destination address was supplied */
    if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp))
      zlog_warn("warning: PtP interface %s with addr %s/%d needs a "
      		"peer address",ifp->name,inet_ntoa(*addr),prefixlen);

  /* Label of this address. */
  if (label)
    ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);

  /* nothing to do? */
  if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL)
    return;
  
  connected_announce (ifp, ifc);
}