Exemple #1
0
static void
print_rnh (struct route_node *rn, struct vty *vty)
{
  struct rnh *rnh;
  struct nexthop *nexthop;
  struct listnode *node;
  struct zserv *client;
  char buf[BUFSIZ];

  rnh = rn->info;
  vty_out(vty, "%s%s", inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ),
	  VTY_NEWLINE);
  if (rnh->state)
    {
      vty_out(vty, " resolved via %s%s",
	      zebra_route_string(rnh->state->type), VTY_NEWLINE);
      for (nexthop = rnh->state->nexthop; nexthop; nexthop = nexthop->next)
	print_nh(nexthop, vty);
    }
  else
    vty_out(vty, " unresolved%s%s",
	    CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) ? "(Connected)" : "",
	    VTY_NEWLINE);

  vty_out(vty, " Client list:");
  for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client))
    vty_out(vty, " %s(fd %d)", zebra_route_string(client->proto),
	    client->sock);
  vty_out(vty, "%s", VTY_NEWLINE);
}
Exemple #2
0
void
isis_redist_delete(int type, struct prefix *p)
{
  int family = p->family;
  struct route_table *ei_table = get_ext_info(isis, family);
  struct route_node *ei_node;
  struct listnode *node;
  struct isis_area *area;
  int level;
  struct isis_redist *redist;

  char debug_buf[BUFSIZ];
  prefix2str(p, debug_buf, sizeof(debug_buf));

  zlog_debug("%s: Removing route %s from %s.", __func__, debug_buf,
             zebra_route_string(type));

  if (is_default(p))
    {
      /* Don't remove default route but add synthetic route for use
       * by "default-information originate always". Areas without the
       * "always" setting will ignore routes with origin DEFAULT_ROUTE. */
      isis_redist_add(DEFAULT_ROUTE, p, 254, MAX_WIDE_PATH_METRIC);
      return;
    }

  if (!ei_table)
    {
      zlog_warn("%s: External information table not initialized.",
                __func__);
      return;
    }

  ei_node = route_node_lookup(ei_table, p);
  if (!ei_node || !ei_node->info)
    {
      char buf[BUFSIZ];
      prefix2str(p, buf, sizeof(buf));
      zlog_warn("%s: Got a delete for %s route %s, but that route"
                " was never added.", __func__, zebra_route_string(type),
                buf);
      if (ei_node)
        route_unlock_node(ei_node);
      return;
    }
  route_unlock_node(ei_node);

  for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
    for (level = 1; level < ISIS_LEVELS; level++)
      {
        redist = get_redist_settings(area, family, type, level);
        if (!redist->redist)
          continue;

        isis_redist_uninstall(area, level, p);
      }

  XFREE(MTYPE_ISIS, ei_node->info);
  route_unlock_node(ei_node);
}
Exemple #3
0
int
zebra_dispatch_rnh_table (vrf_id_t vrfid, int family, struct zserv *client)
{
  struct route_table *ntable;
  struct route_node *nrn;
  struct rnh *rnh;

  ntable = lookup_rnh_table(vrfid, family);
  if (!ntable)
    {
      zlog_debug("dispatch_rnh_table: rnh table not found\n");
      return -1;
    }

  for (nrn = route_top (ntable); nrn; nrn = route_next (nrn))
    {
      if (!nrn->info)
	  continue;

      rnh = nrn->info;
      if (IS_ZEBRA_DEBUG_NHT)
	{
	  char bufn[INET6_ADDRSTRLEN];
	  prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
	  zlog_debug("rnh %s - sending nexthop %s event to client %s", bufn,
		     rnh->state ? "reachable" : "unreachable",
		     zebra_route_string(client->proto));
	}
      send_client(rnh, client, vrfid);
    }
  return 1;
}
Exemple #4
0
int
zebra_cleanup_rnh_client (vrf_id_t vrfid, int family, struct zserv *client)
{
  struct route_table *ntable;
  struct route_node *nrn;
  struct rnh *rnh;

  ntable = lookup_rnh_table(vrfid, family);
  if (!ntable)
    {
      zlog_debug("cleanup_rnh_client: rnh table not found\n");
      return -1;
    }

  for (nrn = route_top (ntable); nrn; nrn = route_next (nrn))
    {
      if (!nrn->info)
	  continue;

      rnh = nrn->info;
      if (IS_ZEBRA_DEBUG_NHT)
	{
	  char bufn[INET6_ADDRSTRLEN];
	  prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
	  zlog_debug("rnh %s - cleaning state for client %s", bufn,
		     zebra_route_string(client->proto));
	}
      zebra_remove_rnh_client(rnh, client);
    }
  return 1;
}
Exemple #5
0
void pim_zebra_init (struct thread_master *master, char *zebra_sock_path)
{
  int i;

  if (zebra_sock_path)
    zclient_serv_path_set(zebra_sock_path);

#ifdef HAVE_TCP_ZEBRA
  zlog_notice("zclient update contacting ZEBRA daemon at socket TCP %s,%d", "127.0.0.1", ZEBRA_PORT);
#else
  zlog_notice("zclient update contacting ZEBRA daemon at socket UNIX %s", zclient_serv_path_get());
#endif

  /* Socket for receiving updates from Zebra daemon */
  qpim_zclient_update = zclient_new (master);

  qpim_zclient_update->zebra_connected          = pim_zebra_connected;
  qpim_zclient_update->router_id_update         = pim_router_id_update_zebra;
  qpim_zclient_update->interface_add            = pim_zebra_if_add;
  qpim_zclient_update->interface_delete         = pim_zebra_if_del;
  qpim_zclient_update->interface_up             = pim_zebra_if_state_up;
  qpim_zclient_update->interface_down           = pim_zebra_if_state_down;
  qpim_zclient_update->interface_address_add    = pim_zebra_if_address_add;
  qpim_zclient_update->interface_address_delete = pim_zebra_if_address_del;
  qpim_zclient_update->ipv4_route_add           = redist_read_ipv4_route;
  qpim_zclient_update->ipv4_route_delete        = redist_read_ipv4_route;

  zclient_init(qpim_zclient_update, ZEBRA_ROUTE_PIM);
  if (PIM_DEBUG_PIM_TRACE) {
    zlog_info("zclient_init cleared redistribution request");
  }

  zassert(qpim_zclient_update->redist_default == ZEBRA_ROUTE_PIM);

  /* Request all redistribution */
  for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
    if (i == qpim_zclient_update->redist_default)
      continue;
    vrf_bitmap_set(qpim_zclient_update->redist[i], VRF_DEFAULT);
    if (PIM_DEBUG_PIM_TRACE) {
      zlog_debug("%s: requesting redistribution for %s (%i)", 
		 __PRETTY_FUNCTION__, zebra_route_string(i), i);
    }
  }

  /* Request default information */
  vrf_bitmap_set(qpim_zclient_update->default_information, VRF_DEFAULT);
  if (PIM_DEBUG_PIM_TRACE) {
    zlog_info("%s: requesting default information redistribution",
	      __PRETTY_FUNCTION__);

    zlog_notice("%s: zclient update socket initialized",
		__PRETTY_FUNCTION__);
  }

  zassert(!qpim_zclient_lookup);
  qpim_zclient_lookup = zclient_lookup_new();
  zassert(qpim_zclient_lookup);
}
Exemple #6
0
void rip_show_redistribute_config(struct vty *vty, struct rip *rip)
{
	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
		if (i == zclient->redist_default
		    || !rip_redistribute_check(rip, i))
			continue;

		vty_out(vty, " %s", zebra_route_string(i));
	}
}
Exemple #7
0
void
zebra_remove_rnh_client (struct rnh *rnh, struct zserv *client)
{
  if (IS_ZEBRA_DEBUG_NHT)
    {
      char buf[INET6_ADDRSTRLEN];
      zlog_debug("client %s unregisters rnh %s",
		 zebra_route_string(client->proto),
		 rnh_str(rnh, buf, INET6_ADDRSTRLEN));
    }
  listnode_delete(rnh->client_list, client);
  if (list_isempty(rnh->client_list))
    zebra_delete_rnh(rnh);
}
Exemple #8
0
/* If client sent routes of specific type, zebra removes it
 * and returns number of deleted routes.
 */
static void
zebra_score_rib (int client_sock)
{
  int i;

  for (i = ZEBRA_ROUTE_RIP; i < ZEBRA_ROUTE_MAX; i++)
    if (client_sock == route_type_oaths[i])
      {
        zlog_notice ("client %d disconnected. %lu %s routes removed from the rib",
                      client_sock, rib_score_proto (i), zebra_route_string (i));
        route_type_oaths[i] = 0;
        break;
      }
}
Exemple #9
0
/* Tie up route-type and client->sock */
static void
zread_hello (struct zserv *client)
{
  /* type of protocol (lib/zebra.h) */
  u_char proto;
  proto = stream_getc (client->ibuf);

  /* accept only dynamic routing protocols */
  if ((proto < ZEBRA_ROUTE_MAX)
  &&  (proto > ZEBRA_ROUTE_STATIC))
    {
      zlog_notice ("client %d says hello and bids fair to announce only %s routes",
                    client->sock, zebra_route_string(proto));

      /* if route-type was binded by other client */
      if (route_type_oaths[proto])
        zlog_warn ("sender of %s routes changed %c->%c",
                    zebra_route_string(proto), route_type_oaths[proto],
                    client->sock);

      route_type_oaths[proto] = client->sock;
    }
}
Exemple #10
0
/* print current babel configuration on vty */
static int
babel_config_write (struct vty *vty)
{
    int lines = 0;
    int i;

    /* list enabled debug modes */
    lines += debug_babel_config_write (vty);

    if (!babel_routing_process)
        return lines;
    vty_out (vty, "router babel%s", VTY_NEWLINE);
    if (diversity_kind != DIVERSITY_NONE)
    {
        vty_out (vty, " babel diversity%s", VTY_NEWLINE);
        lines++;
    }
    if (diversity_factor != BABEL_DEFAULT_DIVERSITY_FACTOR)
    {
        vty_out (vty, " babel diversity-factor %d%s", diversity_factor,
                 VTY_NEWLINE);
        lines++;
    }
    if (resend_delay != BABEL_DEFAULT_RESEND_DELAY)
    {
        vty_out (vty, " babel resend-delay %u%s", resend_delay, VTY_NEWLINE);
        lines++;
    }
    if (smoothing_half_life != BABEL_DEFAULT_SMOOTHING_HALF_LIFE)
    {
        vty_out (vty, " babel smoothing-half-life %u%s",
                 smoothing_half_life, VTY_NEWLINE);
        lines++;
    }
    lines += babel_auth_config_write (vty);
    /* list enabled interfaces */
    lines = 1 + babel_enable_if_config_write (vty);
    /* list redistributed protocols */
    for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
        if (i != zclient->redist_default && zclient->redist[i])
        {
            vty_out (vty, " redistribute %s%s", zebra_route_string (i), VTY_NEWLINE);
            lines++;
        }

    lines += config_write_distribute (vty);

    return lines;
}
Exemple #11
0
/* Handle notification about route being added */
void
isis_redist_add(int type, struct prefix *p, u_char distance, uint32_t metric)
{
  int family = p->family;
  struct route_table *ei_table = get_ext_info(isis, family);
  struct route_node *ei_node;
  struct isis_ext_info *info;
  struct listnode *node;
  struct isis_area *area;
  int level;
  struct isis_redist *redist;

  char debug_buf[BUFSIZ];
  prefix2str(p, debug_buf, sizeof(debug_buf));

  zlog_debug("%s: New route %s from %s.", __func__, debug_buf,
             zebra_route_string(type));

  if (!ei_table)
    {
      zlog_warn("%s: External information table not initialized.",
                __func__);
      return;
    }

  ei_node = route_node_get(ei_table, p);
  if (ei_node->info)
    route_unlock_node(ei_node);
  else
    ei_node->info = XCALLOC(MTYPE_ISIS, sizeof(struct isis_ext_info));

  info = ei_node->info;
  info->origin = type;
  info->distance = distance;
  info->metric = metric;

  if (is_default(p))
    type = DEFAULT_ROUTE;

  for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
    for (level = 1; level <= ISIS_LEVELS; level++)
      {
        redist = get_redist_settings(area, family, type, level);
        if (!redist->redist)
          continue;

        isis_redist_update_ext_reach(area, level, redist, p, info);
      }
}
Exemple #12
0
void
zebra_add_rnh_client (struct rnh *rnh, struct zserv *client, vrf_id_t vrf_id)
{
  if (IS_ZEBRA_DEBUG_NHT)
    {
      char buf[INET6_ADDRSTRLEN];
      zlog_debug("client %s registers rnh %s",
		 zebra_route_string(client->proto),
		 rnh_str(rnh, buf, INET6_ADDRSTRLEN));
    }
  if (!listnode_lookup(rnh->client_list, client))
    {
      listnode_add(rnh->client_list, client);
      send_client(rnh, client, vrf_id);
    }
}
Exemple #13
0
/* Unset redistribution.  */
int
bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type)
{
  /* Unset flag from BGP instance. */
  bgp->redist[afi][type] = 0;

  /* Unset route-map. */
  if (bgp->rmap[afi][type].name)
    free (bgp->rmap[afi][type].name);
  bgp->rmap[afi][type].name = NULL;
  bgp->rmap[afi][type].map = NULL;

  /* Unset metric. */
  bgp->redist_metric_flag[afi][type] = 0;
  bgp->redist_metric[afi][type] = 0;

  /* Return if zebra connection is disabled. */
  if (! vrf_bitmap_check (zclient->redist[type], VRF_DEFAULT))
    return CMD_WARNING;
  vrf_bitmap_unset (zclient->redist[type], VRF_DEFAULT);

  if (bgp->redist[AFI_IP][type] == 0 
      && bgp->redist[AFI_IP6][type] == 0 
      && zclient->sock >= 0)
    {
      /* Send distribute delete message to zebra. */
      if (BGP_DEBUG(zebra, ZEBRA))
	zlog_debug("Zebra send: redistribute delete %s",
		   zebra_route_string(type));
      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type,
                               VRF_DEFAULT);
    }
  
  /* Withdraw redistributed routes from current BGP's routing table. */
  bgp_redistribute_withdraw (bgp, afi, type);

  return CMD_SUCCESS;
}
Exemple #14
0
/* Other routes redistribution into BGP. */
int
bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type)
{
  /* Set flag to BGP instance. */
  bgp->redist[afi][type] = 1;

  /* Return if already redistribute flag is set. */
  if (zclient->redist[type])
    return CMD_WARNING;

  zclient->redist[type] = 1;

  /* Return if zebra connection is not established. */
  if (zclient->sock < 0)
    return CMD_WARNING;

  if (BGP_DEBUG(zebra, ZEBRA))
    zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type));
    
  /* Send distribute add message to zebra. */
  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);

  return CMD_SUCCESS;
}
Exemple #15
0
/* Zebra route add and delete treatment. */
static int
zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length,
    vrf_id_t vrf_id)
{
  struct stream *s;
  struct zapi_ipv4 api;
  struct in_addr nexthop;
  struct prefix_ipv4 p;
  unsigned char plength = 0;

  s = zclient->ibuf;
  nexthop.s_addr = 0;

  /* Type, flags, message. */
  api.type = stream_getc (s);
  api.flags = stream_getc (s);
  api.message = stream_getc (s);

  /* IPv4 prefix. */
  memset (&p, 0, sizeof (struct prefix_ipv4));
  p.family = AF_INET;
  plength = stream_getc (s);
  p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, plength);
  stream_get (&p.prefix, s, PSIZE (p.prefixlen));

  /* Nexthop, ifindex, distance, metric. */
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    {
      api.nexthop_num = stream_getc (s);
      nexthop.s_addr = stream_get_ipv4 (s);
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
    {
      api.ifindex_num = stream_getc (s);
      stream_getl (s); /* ifindex, unused */
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
    api.distance = stream_getc (s);
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
    api.metric = stream_getl (s);
  else
    api.metric = 0;

  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
    api.tag = stream_getl (s);
  else
    api.tag = 0;

  if (command == ZEBRA_IPV4_ROUTE_ADD)
    {
      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  char buf[2][INET_ADDRSTRLEN];
	  zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u tag %d",
		     zebra_route_string(api.type),
		     inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
		     p.prefixlen,
		     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
		     api.metric,
		     api.tag);
	}
      bgp_redistribute_add ((struct prefix *)&p, &nexthop, NULL,
			    api.metric, api.type, api.tag);
    }
  else
    {
      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  char buf[2][INET_ADDRSTRLEN];
	  zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
		     "nexthop %s metric %u tag %d",
		     zebra_route_string(api.type),
		     inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
		     p.prefixlen,
		     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
		     api.metric,
		     api.tag);
	}
      bgp_redistribute_delete((struct prefix *)&p, api.type);
    }

  return 0;
}
Exemple #16
0
static int redist_read_ipv4_route(int command, struct zclient *zclient,
				  zebra_size_t length, vrf_id_t vrf_id)
{
  struct stream *s;
  struct zapi_ipv4 api;
  unsigned long ifindex;
  struct in_addr nexthop;
  struct prefix_ipv4 p;
  int min_len = 4;

  if (length < min_len) {
    zlog_warn("%s %s: short buffer: length=%d min=%d",
	      __FILE__, __PRETTY_FUNCTION__,
	      length, min_len);
    return -1;
  }

  s = zclient->ibuf;
  ifindex = 0;
  nexthop.s_addr = 0;

  /* Type, flags, message. */
  api.type = stream_getc(s);
  api.flags = stream_getc(s);
  api.message = stream_getc(s);

  /* IPv4 prefix length. */
  memset(&p, 0, sizeof(struct prefix_ipv4));
  p.family = AF_INET;
  p.prefixlen = stream_getc(s);

  min_len +=
    PSIZE(p.prefixlen) +
    CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? 5 : 0 +
    CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? 5 : 0 +
    CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? 1 : 0 +
    CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? 4 : 0;

  if (PIM_DEBUG_ZEBRA) {
    zlog_debug("%s %s: length=%d min_len=%d flags=%s%s%s%s",
	       __FILE__, __PRETTY_FUNCTION__,
	       length, min_len,
	       CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? "nh" : "",
	       CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? " ifi" : "",
	       CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? " dist" : "",
	       CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : "");
  }

  if (length < min_len) {
    zlog_warn("%s %s: short buffer: length=%d min_len=%d flags=%s%s%s%s",
	      __FILE__, __PRETTY_FUNCTION__,
	      length, min_len,
	      CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? "nh" : "",
	      CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? " ifi" : "",
	      CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? " dist" : "",
	      CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : "");
    return -1;
  }

  /* IPv4 prefix. */
  stream_get(&p.prefix, s, PSIZE(p.prefixlen));

  /* Nexthop, ifindex, distance, metric. */
  if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) {
    api.nexthop_num = stream_getc(s);
    nexthop.s_addr = stream_get_ipv4(s);
  }
  if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) {
    api.ifindex_num = stream_getc(s);
    ifindex = stream_getl(s);
  }

  api.distance = CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ?
    stream_getc(s) :
    0;

  api.metric = CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ?
    stream_getl(s) :
    0;

  switch (command) {
  case ZEBRA_IPV4_ROUTE_ADD:
    if (PIM_DEBUG_ZEBRA) {
      char buf[2][INET_ADDRSTRLEN];
      zlog_debug("%s: add %s %s/%d "
		 "nexthop %s ifindex %ld metric%s %u distance%s %u",
		 __PRETTY_FUNCTION__,
		 zebra_route_string(api.type),
		 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
		 p.prefixlen,
		 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
		 ifindex,
		 CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? "-recv" : "-miss",
		 api.metric,
		 CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? "-recv" : "-miss",
		 api.distance);
    }
    break;
  case ZEBRA_IPV4_ROUTE_DELETE:
    if (PIM_DEBUG_ZEBRA) {
      char buf[2][INET_ADDRSTRLEN];
      zlog_debug("%s: delete %s %s/%d "
		 "nexthop %s ifindex %ld metric%s %u distance%s %u",
		 __PRETTY_FUNCTION__,
		 zebra_route_string(api.type),
		 inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
		 p.prefixlen,
		 inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
		 ifindex,
		 CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? "-recv" : "-miss",
		 api.metric,
		 CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? "-recv" : "-miss",
		 api.distance);
    }
    break;
  default:
    zlog_warn("%s: unknown command=%d", __PRETTY_FUNCTION__, command);
    return -1;
  }

  sched_rpf_cache_refresh();

  return 0;
}
Exemple #17
0
const char *ospf_redist_string(unsigned int route_type)
{
	return (route_type == ZEBRA_ROUTE_MAX) ? "Default"
					       : zebra_route_string(route_type);
}
Exemple #18
0
static int
ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
                       zebra_size_t length)
{
  struct stream *s;
  struct zapi_ipv6 api;
  unsigned long ifindex;
  struct prefix_ipv6 p;
  struct in6_addr *nexthop;

  s = zclient->ibuf;
  ifindex = 0;
  nexthop = NULL;
  memset (&api, 0, sizeof (api));

  /* Type, flags, message. */
  api.type = stream_getc (s);
  api.flags = stream_getc (s);
  api.message = stream_getc (s);

  /* IPv6 prefix. */
  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = stream_getc (s);
  stream_get (&p.prefix, s, PSIZE (p.prefixlen));

  /* Nexthop, ifindex, distance, metric. */
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    {
      api.nexthop_num = stream_getc (s);
      nexthop = (struct in6_addr *)
        malloc (api.nexthop_num * sizeof (struct in6_addr));
      stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr));
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
    {
      api.ifindex_num = stream_getc (s);
      ifindex = stream_getl (s);
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
    api.distance = stream_getc (s);
  else
    api.distance = 0;
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
    api.metric = stream_getl (s);
  else
    api.metric = 0;

  if (IS_OSPF6_DEBUG_ZEBRA (RECV))
    {
      char prefixstr[128], nexthopstr[128];
      prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr));
      if (nexthop)
        inet_ntop (AF_INET6, nexthop, nexthopstr, sizeof (nexthopstr));
      else
        snprintf (nexthopstr, sizeof (nexthopstr), "::");

      zlog_debug ("Zebra Receive route %s: %s %s nexthop %s ifindex %ld",
		  (command == ZEBRA_IPV6_ROUTE_ADD ? "add" : "delete"),
		  zebra_route_string(api.type), prefixstr, nexthopstr, ifindex);
    }
 
  if (command == ZEBRA_IPV6_ROUTE_ADD)
    ospf6_asbr_redistribute_add (api.type, ifindex, (struct prefix *) &p,
                                 api.nexthop_num, nexthop);
  else
    ospf6_asbr_redistribute_remove (api.type, ifindex, (struct prefix *) &p);

  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    free (nexthop);

  return 0;
}
Exemple #19
0
/* Zebra route add and delete treatment. */
static int
zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
{
  struct stream *s;
  struct zapi_ipv6 api;
  struct in6_addr nexthop;
  struct prefix_ipv6 p;

  s = zclient->ibuf;
  memset (&nexthop, 0, sizeof (struct in6_addr));

  /* Type, flags, message. */
  api.type = stream_getc (s);
  api.flags = stream_getc (s);
  api.message = stream_getc (s);

  /* IPv6 prefix. */
  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = stream_getc (s);
  stream_get (&p.prefix, s, PSIZE (p.prefixlen));

  /* Nexthop, ifindex, distance, metric. */
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    {
      api.nexthop_num = stream_getc (s);
      stream_get (&nexthop, s, 16);
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
    {
      api.ifindex_num = stream_getc (s);
      stream_getl (s); /* ifindex, unused */
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
    api.distance = stream_getc (s);
  else
    api.distance = 0;
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
    api.metric = stream_getl (s);
  else
    api.metric = 0;

  /* Simply ignore link-local address. */
  if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
    return 0;

  if (command == ZEBRA_IPV6_ROUTE_ADD)
    {
      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  char buf[2][INET6_ADDRSTRLEN];
	  zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d nexthop %s metric %u",
		     zebra_route_string(api.type),
		     inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
		     p.prefixlen,
		     inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
		     api.metric);
	}
      bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
			    api.metric, api.type);
    }
  else
    {
      if (BGP_DEBUG(zebra, ZEBRA))
	{
	  char buf[2][INET6_ADDRSTRLEN];
	  zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d "
		     "nexthop %s metric %u",
		     zebra_route_string(api.type),
		     inet_ntop(AF_INET6, &p.prefix, buf[0], sizeof(buf[0])),
		     p.prefixlen,
		     inet_ntop(AF_INET6, &nexthop, buf[1], sizeof(buf[1])),
		     api.metric);
	}
      bgp_redistribute_delete ((struct prefix *) &p, api.type);
    }
  
  return 0;
}