Beispiel #1
0
/* show neighbor structure */
void
ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
{
  char router_id[16];
  char duration[16];
  struct timeval now, res;
  char nstate[16];
  char deadtime[16];
  long h, m, s;

  /* Router-ID (Name) */
  inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
#ifdef HAVE_GETNAMEINFO
  {
  }
#endif /*HAVE_GETNAMEINFO*/

  gettimeofday (&now, NULL);

  /* Dead time */
  h = m = s = 0;
  if (on->inactivity_timer)
    {
      s = on->inactivity_timer->u.sands.tv_sec - now.tv_sec;
      h = s / 3600;
      s -= h * 3600;
      m = s / 60;
      s -= m * 60;
    }
  snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s);

  /* Neighbor State */
  if (if_is_pointopoint (on->ospf6_if->interface))
    snprintf (nstate, sizeof (nstate), "PointToPoint");
  else
    {
      if (on->router_id == on->drouter)
        snprintf (nstate, sizeof (nstate), "DR");
      else if (on->router_id == on->bdrouter)
        snprintf (nstate, sizeof (nstate), "BDR");
      else
        snprintf (nstate, sizeof (nstate), "DROther");
    }

  /* Duration */
  timersub (&now, &on->last_changed, &res);
  timerstring (&res, duration, sizeof (duration));

  /*
  vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
           "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
           "I/F", "State", VNL);
  */

  vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
           router_id, on->priority, deadtime,
           ospf6_neighbor_state_str[on->state], nstate, duration,
           on->ospf6_if->interface->name,
           ospf6_interface_state_str[on->ospf6_if->state], VNL);
}
Beispiel #2
0
/* Interface State Machine */
int
interface_up (struct thread *thread)
{
  struct ospf6_interface *oi;

  oi = (struct ospf6_interface *) THREAD_ARG (thread);
  assert (oi && oi->interface);

  if (IS_OSPF6_DEBUG_INTERFACE)
    zlog_debug ("Interface Event %s: [InterfaceUp]",
		oi->interface->name);

  /* check physical interface is up */
  if (! if_is_up (oi->interface))
    {
      if (IS_OSPF6_DEBUG_INTERFACE)
        zlog_debug ("Interface %s is down, can't execute [InterfaceUp]",
		    oi->interface->name);
      return 0;
    }

  /* if already enabled, do nothing */
  if (oi->state > OSPF6_INTERFACE_DOWN)
    {
      if (IS_OSPF6_DEBUG_INTERFACE)
        zlog_debug ("Interface %s already enabled",
		    oi->interface->name);
      return 0;
    }

  /* Join AllSPFRouters */
  // send join allspfrouters message to shim 
  thread_add_event (master, rospf6_join_allspfrouters_send, oi, 0);
//  ospf6_join_allspfrouters (oi->interface->ifindex);

  /* Update interface route */
  ospf6_interface_connected_route_update (oi->interface);

  zlog_debug("about to send hello message...");

  /* Schedule Hello */
  if (! CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
    thread_add_event (master, rospf6_hello_send, oi, 0);

  /* decide next interface state */
  if (if_is_pointopoint (oi->interface))
    ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi);
  else if (oi->priority == 0)
    ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi);
  else
    {
      ospf6_interface_state_change (OSPF6_INTERFACE_WAITING, oi);
      thread_add_timer (master, wait_timer, oi, oi->dead_interval);
    }

  return 0;
}
Beispiel #3
0
u_char ospf_default_iftype(struct interface * ifp)
{
	if (if_is_pointopoint(ifp))
		return OSPF_IFTYPE_POINTOPOINT;
	else if (if_is_loopback(ifp))
		return OSPF_IFTYPE_LOOPBACK;
	else
		return OSPF_IFTYPE_BROADCAST;
}
/* Send RIP request packet to specified interface. */
static void
rip_request_interface_send (struct interface *ifp, u_char version)
{
  struct sockaddr_in to;

  /* RIPv2 support multicast. */
  if (version == RIPv2 && if_is_multicast (ifp))
    {
      
      if (IS_RIP_DEBUG_EVENT)
	zlog_debug ("multicast request on %s", ifp->name);

      rip_request_send (NULL, ifp, version, NULL);
      return;
    }

  /* RIPv1 and non multicast interface. */
  if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
    {
      struct listnode *cnode, *cnnode;
      struct connected *connected;

      if (IS_RIP_DEBUG_EVENT)
	zlog_debug ("broadcast request to %s", ifp->name);

      for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
	{
	  if (connected->address->family == AF_INET)
	    {
	      memset (&to, 0, sizeof (struct sockaddr_in));
	      to.sin_port = htons (RIP_PORT_DEFAULT);
              if (connected->destination)
                /* use specified broadcast or peer destination addr */
                to.sin_addr = connected->destination->u.prefix4;
              else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
	        /* calculate the appropriate broadcast address */
                to.sin_addr.s_addr =
		  ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
				      connected->address->prefixlen);
	      else
		/* do not know where to send the packet */
	        continue;

	      if (IS_RIP_DEBUG_EVENT)
		zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
	      
	      rip_request_send (&to, ifp, version, connected);
	    }
	}
    }
}
Beispiel #5
0
void
connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;
  struct prefix_ipv6 *addr;
  struct prefix_ipv6 *dest;

  
  if(product != NULL && product->board_type != BOARD_IS_ACTIVE_MASTER)
  	goto skip;
 #if 0
/*ipv6 not support interface loacal*/
  if(product != NULL && product->board_type == BOARD_IS_ACTIVE_MASTER &&CHECK_FLAG(ifp->if_scope, INTERFACE_LOCAL))
  	goto skip;/*local interface , skip the check the ifc->conf, because the ip address not install in the kernel .*/
#endif
  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;

skip:
  addr = (struct prefix_ipv6 *) ifc->address;
  dest = (struct prefix_ipv6 *) ifc->destination;

  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = addr->prefixlen;

  if (if_is_pointopoint (ifp) && dest)
    {
      if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
	p.prefix = addr->prefix;
      else
	p.prefix = dest->prefix;
    }
  else
    p.prefix = addr->prefix;

  /* Apply mask to the network. */
  apply_mask_ipv6 (&p);

#if ! defined (MUSICA) && ! defined (LINUX)
  /* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */
  if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
    return;
#endif

  rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0,
                ifp->metric, 0);

  rib_update ();
}
Beispiel #6
0
void
connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;
  struct prefix_ipv6 *addr;
  struct prefix_ipv6 *dest;

  if(product != NULL && product->board_type != BOARD_IS_ACTIVE_MASTER)
   goto skip;
  
  if(product != NULL && product->board_type == BOARD_IS_ACTIVE_MASTER &&CHECK_FLAG(ifp->if_scope, INTERFACE_LOCAL))
   goto skip;/*local interface , skip the check the ifc->conf, because the ip address not install in the kernel .*/

  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;
  
skip:
  addr = (struct prefix_ipv6 *) ifc->address;
  dest = (struct prefix_ipv6 *) ifc->destination;

  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = addr->prefixlen;

  if (if_is_pointopoint (ifp) && dest)
    {
      if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
	p.prefix = addr->prefix;
      else
	p.prefix = dest->prefix;
    }
  else
    p.prefix = addr->prefix;

  apply_mask_ipv6 (&p);

  if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
    return;

  rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);

  rib_update ();
}
void
connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;
  struct prefix_ipv6 *addr;
  struct prefix_ipv6 *dest;

  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;

  addr = (struct prefix_ipv6 *) ifc->address;
  dest = (struct prefix_ipv6 *) ifc->destination;

  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = addr->prefixlen;

  if (if_is_pointopoint (ifp) && dest)
    {
      if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
	p.prefix = addr->prefix;
      else
	p.prefix = dest->prefix;
    }
  else
    p.prefix = addr->prefix;

  /* Apply mask to the network. */
  apply_mask_ipv6 (&p);

#if ! defined (MUSICA) && ! defined (LINUX)
  /* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */
  if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
    return;
#endif

  rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0,
                ifp->metric, 0);

  rib_update ();
}
Beispiel #8
0
/*
 * Create the socket and set the tx/rx funcs
 */
int
isis_sock_init (struct isis_circuit *circuit)
{
  int retval = ISIS_OK;

  if (isisd_privs.change (ZPRIVS_RAISE))
    zlog_err ("%s: could not raise privs, %s", __func__, safe_strerror (errno));

  retval = open_packet_socket (circuit);

  if (retval != ISIS_OK)
    {
      zlog_warn ("%s: could not initialize the socket", __func__);
      goto end;
    }

  /* Assign Rx and Tx callbacks are based on real if type */
  if (if_is_broadcast (circuit->interface))
    {
      circuit->tx = isis_send_pdu_bcast;
      circuit->rx = isis_recv_pdu_bcast;
    }
  else if (if_is_pointopoint (circuit->interface))
    {
      circuit->tx = isis_send_pdu_p2p;
      circuit->rx = isis_recv_pdu_p2p;
    }
  else
    {
      zlog_warn ("isis_sock_init(): unknown circuit type");
      retval = ISIS_WARNING;
      goto end;
    }

end:
  if (isisd_privs.change (ZPRIVS_LOWER))
    zlog_err ("%s: could not lower privs, %s", __func__, safe_strerror (errno));

  return retval;
}
void
connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;
  struct prefix_ipv6 *addr;
  struct prefix_ipv6 *dest;

  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;

  addr = (struct prefix_ipv6 *) ifc->address;
  dest = (struct prefix_ipv6 *) ifc->destination;

  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = addr->prefixlen;

  if (if_is_pointopoint (ifp) && dest)
    {
      if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix))
	p.prefix = addr->prefix;
      else
	p.prefix = dest->prefix;
    }
  else
    p.prefix = addr->prefix;

  apply_mask_ipv6 (&p);

  if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
    return;

  rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);

  rib_update ();
}
Beispiel #10
0
/* Interface's address information get. */
int
ifam_read (struct ifa_msghdr *ifam)
{
  struct interface *ifp = NULL;
  union sockunion addr, mask, brd;
  char ifname[INTERFACE_NAMSIZ];
  short ifnlen = 0;
  char isalias = 0;
  int flags = 0;
  
  ifname[0] = ifname[INTERFACE_NAMSIZ - 1] = '\0';
  
  /* Allocate and read address information. */
  ifam_read_mesg (ifam, &addr, &mask, &brd, ifname, &ifnlen);
  
  if ((ifp = if_lookup_by_index(ifam->ifam_index)) == NULL)
    {
      zlog_warn ("%s: no interface for ifname %s, index %d", 
                 __func__, ifname, ifam->ifam_index);
      return -1;
    }
  
  if (ifnlen && strncmp (ifp->name, ifname, INTERFACE_NAMSIZ))
    isalias = 1;
  
  /* N.B. The info in ifa_msghdr does not tell us whether the RTA_BRD
     field contains a broadcast address or a peer address, so we are forced to
     rely upon the interface type. */
  if (if_is_pointopoint(ifp))
    SET_FLAG(flags, ZEBRA_IFA_PEER);

#if 0
  /* it might seem cute to grab the interface metric here, however
   * we're processing an address update message, and so some systems
   * (e.g. FBSD) dont bother to fill in ifam_metric. Disabled, but left
   * in deliberately, as comment.
   */
  ifp->metric = ifam->ifam_metric;
#endif

  /* Add connected address. */
  switch (sockunion_family (&addr))
    {
    case AF_INET:
      if (ifam->ifam_type == RTM_NEWADDR)
	connected_add_ipv4 (ifp, flags, &addr.sin.sin_addr, 
			    ip_masklen (mask.sin.sin_addr),
			    &brd.sin.sin_addr,
			    (isalias ? ifname : NULL));
      else
	connected_delete_ipv4 (ifp, flags, &addr.sin.sin_addr, 
			       ip_masklen (mask.sin.sin_addr),
			       &brd.sin.sin_addr);
      break;
#ifdef HAVE_IPV6
    case AF_INET6:
      /* Unset interface index from link-local address when IPv6 stack
	 is KAME. */
      if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr))
	SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0);

      if (ifam->ifam_type == RTM_NEWADDR)
	connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr, 
			    ip6_masklen (mask.sin6.sin6_addr),
			    &brd.sin6.sin6_addr,
			    (isalias ? ifname : NULL));
      else
	connected_delete_ipv6 (ifp,
			       &addr.sin6.sin6_addr, 
			       ip6_masklen (mask.sin6.sin6_addr),
			       &brd.sin6.sin6_addr);
      break;
#endif /* HAVE_IPV6 */
    default:
      /* Unsupported family silently ignore... */
      break;
    }
  
  /* Check interface flag for implicit up of the interface. */
  if_refresh (ifp);

#ifdef SUNOS_5
  /* In addition to lacking IFANNOUNCE, on SUNOS IFF_UP is strange. 
   * See comments for SUNOS_5 in interface.c::if_flags_mangle.
   * 
   * Here we take care of case where the real IFF_UP was previously
   * unset (as kept in struct zebra_if.primary_state) and the mangled
   * IFF_UP (ie IFF_UP set || listcount(connected) has now transitioned
   * to unset due to the lost non-primary address having DELADDR'd.
   *
   * we must delete the interface, because in between here and next
   * event for this interface-name the administrator could unplumb
   * and replumb the interface.
   */
  if (!if_is_up (ifp))
    if_delete_update (ifp);
#endif /* SUNOS_5 */
  
  return 0;
}
Beispiel #11
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);
}
Beispiel #12
0
/* show specified interface structure */
static int
ospf6_interface_show (struct vty *vty, struct interface *ifp)
{
  struct ospf6_interface *oi;
  struct connected *c;
  struct prefix *p;
  struct listnode *i;
  char strbuf[64], drouter[32], bdrouter[32];
  const char *updown[3] = {"down", "up", NULL};
  const char *type;
  struct timeval res, now;
  char duration[32];
  struct ospf6_lsa *lsa;

  /* check physical interface type */
  if (if_is_loopback (ifp))
    type = "LOOPBACK";
  else if (if_is_broadcast (ifp))
    type = "BROADCAST";
  else if (if_is_pointopoint (ifp))
    type = "POINTOPOINT";
  else
    type = "UNKNOWN";

  vty_out (vty, "%s is %s, type %s%s",
           ifp->name, updown[if_is_up (ifp)], type,
	   VNL);
  vty_out (vty, "  Interface ID: %d%s", ifp->ifindex, VNL);

  if (ifp->info == NULL)
    {
      vty_out (vty, "   OSPF not enabled on this interface%s", VNL);
      return 0;
    }
  else
    oi = (struct ospf6_interface *) ifp->info;

  vty_out (vty, "  Internet Address:%s", VNL);

  for (ALL_LIST_ELEMENTS_RO (ifp->connected, i, c))
    {
      p = c->address;
      prefix2str (p, strbuf, sizeof (strbuf));
      switch (p->family)
        {
        case AF_INET:
          vty_out (vty, "    inet : %s%s", strbuf,
		   VNL);
          break;
        case AF_INET6:
          vty_out (vty, "    inet6: %s%s", strbuf,
		   VNL);
          break;
        default:
          vty_out (vty, "    ???  : %s%s", strbuf,
		   VNL);
          break;
        }
    }

  if (oi->area)
    {
      vty_out (vty, "  Instance ID %d, Interface MTU %d (autodetect: %d)%s",
	       oi->instance_id, oi->ifmtu, ifp->mtu6, VNL);
      vty_out (vty, "  MTU mismatch detection: %s%s", oi->mtu_ignore ?
	       "disabled" : "enabled", VNL);
      inet_ntop (AF_INET, &oi->area->area_id,
                 strbuf, sizeof (strbuf));
      vty_out (vty, "  Area ID %s, Cost %hu%s", strbuf, oi->cost,
	       VNL);
    }
  else
    vty_out (vty, "  Not Attached to Area%s", VNL);

  vty_out (vty, "  State %s, Transmit Delay %d sec, Priority %d%s",
           ospf6_interface_state_str[oi->state],
           oi->transdelay, oi->priority,
	   VNL);
  vty_out (vty, "  Timer intervals configured:%s", VNL);
  vty_out (vty, "   Hello %d, Dead %d, Retransmit %d%s",
           oi->hello_interval, oi->dead_interval, oi->rxmt_interval,
	   VNL);

  inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter));
  inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter));
  vty_out (vty, "  DR: %s BDR: %s%s", drouter, bdrouter, VNL);

  vty_out (vty, "  Number of I/F scoped LSAs is %u%s",
           oi->lsdb->count, VNL);

  bane_gettime (BANE_CLK_MONOTONIC, &now);

  timerclear (&res);
  if (oi->thread_send_lsupdate)
    timersub (&oi->thread_send_lsupdate->u.sands, &now, &res);
  timerstring (&res, duration, sizeof (duration));
  vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
           oi->lsupdate_list->count, duration,
           (oi->thread_send_lsupdate ? "on" : "off"),
           VNL);
  for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VNL);

  timerclear (&res);
  if (oi->thread_send_lsack)
    timersub (&oi->thread_send_lsack->u.sands, &now, &res);
  timerstring (&res, duration, sizeof (duration));
  vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
           oi->lsack_list->count, duration,
           (oi->thread_send_lsack ? "on" : "off"),
           VNL);
  for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
       lsa = ospf6_lsdb_next (lsa))
    vty_out (vty, "      %s%s", lsa->name, VNL);

  return 0;
}
Beispiel #13
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);
}
Beispiel #14
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);
}