Esempio n. 1
0
s32 bgp_nlri_parse_6pe (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
{
  u_char *pnt;
  u_char *lim;
  struct prefix p;
  int psize;
  int prefixlen;
  u_int32_t label;
  u_char *tagpnt;

  /* Check peer status. */
  if (peer->status != Established)
    return 0;

  pnt = packet->nlri;
  lim = pnt + packet->length;

  for (; pnt < lim; pnt += psize)
    {
      /* Clear prefix structure. */
      memset (&p, 0, sizeof (struct prefix));

      /* Fetch prefix length. */
      prefixlen = *pnt++;
      p.family = AF_INET6;
      psize = PSIZE (prefixlen);

      if (prefixlen < 24)
    {
      zlog_err ("prefix length is less than 88: %d", prefixlen);
      return -1;
    }

      label = decode_label (pnt);

      /* Copyr label to prefix. */
      tagpnt = pnt;

      p.prefixlen = prefixlen - 24;
      memcpy (&p.u.prefix, pnt + 3, psize - 3);

      if (pnt + psize > lim)
    return -1;

      if (attr)
    bgp_update (peer, &p, attr, AFI_IP6, SAFI_UNICAST,
            ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, tagpnt, 0);
      else
    bgp_withdraw (peer, &p, attr, AFI_IP6, SAFI_UNICAST,
              ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, tagpnt);
    }

  /* Packet length consistency check. */
  if (pnt != lim)
    return -1;

  return 0;
}
Esempio n. 2
0
s32 bgp_fec_announce_6pe(struct zclient *zc, struct prefix *p, struct bgp_info *info, struct bgp *bgp)
{
    u32 flags = 0;
    struct stream * s  = zc->obuf ;
    struct peer * peer = info->peer ;
    u32 gateway ,label ;
    struct rtm_fec_info_key key;
    struct in6_addr *nexthop = NULL;

    if( !info || !info->attr || !info->attr->extra ) 
        return -1 ;
        
    if (info->attr->extra->mp_nexthop_len == 16)
    {
    	nexthop = &info->attr->extra->mp_nexthop_global;
    }  
    /* If both global and link-local address present. */
    else if (info->attr->extra->mp_nexthop_len == 32)
	{
	    /* Workaround for Cisco's nexthop bug.  */
	    if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
	        && peer->su_remote->sa.sa_family == AF_INET6)
	    	nexthop = &peer->su_remote->sin6.sin6_addr;
	    else
	    	nexthop = &info->attr->extra->mp_nexthop_local;
	}
	if(NULL == nexthop || !IN6_IS_ADDR_V4MAPPED(nexthop))
	{
	    return -1;
	}
	memcpy (&gateway , ((s8 *)nexthop) + 12, 4);
    label  = decode_label ( bgp_info_extra_get(info)->tag) ;

    SET_FLAG(flags, ZAPI_FEC_GATEWAY);
    stream_reset(s);
    zclient_create_header(s,ZEBRA_MPLS_FEC6_INFO_ADD);
    stream_put_prefix(s,p);
	stream_putl(s, flags);
    stream_putl(s, ZEBRA_FEC_TYPE_6PE);
    if( peer )
        stream_putl(s,peer->nexthop.v4.s_addr);
    else
        stream_putl(s,0); // lsr_id = 0 
    stream_putl(s,label);
    stream_putl(s,gateway);

    stream_putw_at (s, 0, stream_get_endp (s));
    key.peer_addr = gateway;

    return rtm_fec_send(ZEBRA_MPLS_FEC6_INFO_ADD, zc, p, s, &key) ;
}
Esempio n. 3
0
s32 bgp_fec_announce_6vpe(bgp_litevrf_config_t *litevrf, struct prefix *p, struct bgp_info *info)
{
    u32 flags = 0;
    struct stream * s  = zclient->obuf ;
    struct peer * peer = info->peer ;
    u32 gateway ,label ;
    struct rtm_fec_info_key key;
    struct in6_addr *nexthop = NULL;

    if( !info || !info->attr || !info->attr->extra ) 
        return -1 ;
        
    nexthop = &info->attr->extra->mp_nexthop_global;

    
	if(NULL == nexthop || !IN6_IS_ADDR_V4MAPPED(nexthop))
	{
	    return -1;
	}
	memcpy (&gateway , ((s8 *)nexthop) + 12, 4);
    label  = decode_label ( bgp_info_extra_get(info)->tag) ;

    SET_FLAG(flags, ZAPI_FEC_GATEWAY|ZAPI_FEC_LITEVRF);
    stream_reset(s);
    zclient_create_header(s,ZEBRA_MPLS_FEC6_INFO_ADD);
    stream_put_prefix(s,p);
	stream_putl(s, flags);
	stream_putl(s,litevrf->id);
    stream_putl(s, ZEBRA_FEC_TYPE_6VPE);
    if( peer )
        stream_putl(s,peer->nexthop.v4.s_addr);
    else
        stream_putl(s,0); // lsr_id = 0 
    stream_putl(s,label);
    stream_putl(s,gateway);

    stream_putw_at (s, 0, stream_get_endp (s));
    key.peer_addr = gateway;

    return rtm_fec_send(ZEBRA_MPLS_FEC6_INFO_ADD, zclient, p, s, &key) ;
}
Esempio n. 4
0
int xkas::eval_integer(const char *&s) {
	if(!*s) throw "nall::bad_eval_integer";
	int value = 0, x = *s, y = *(s + 1);

	//label
	if(x == '.' || x == '_' || (x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z')) {
		const char *start = s;
		s += 1;

		for(;;) {
			if(*s == ':' || *s == '.' || *s == '_' || (*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z') || (*s >= '0' && *s <= '9')) {
				s++;
				continue;
			}
			break;
		}

		string name;
		strlcpy(name, start, s - start + 1);
		if(decode_label(name) == false) throw "nall::bad_eval_integer";
		unsigned offset;
		if(find_label(name, offset) == true) return offset;
		if(pass == 1) return 0; //label may not have been found in first pass (may occur later on)
		throw "nall::bad_eval_integer";
	}

	//hexadecimal
	if(x == '$' || (x == '0' && (y == 'X' || y == 'x'))) {
		s += (x == '$' ? 1 : 2);
		for(;;) {
			if(*s >= '0' && *s <= '9') { value = value * 16 + (*s++ - '0');      continue; }
			if(*s >= 'A' && *s <= 'F') { value = value * 16 + (*s++ - 'A' + 10); continue; }
			if(*s >= 'a' && *s <= 'f') { value = value * 16 + (*s++ - 'a' + 10); continue; }
			return value;
		}
	}

	//binary
	if(x == '%' || (x == '0' && (y == 'B' || y == 'b'))) {
		s += (x == '%' ? 1 : 2);
		for(;;) {
			if(*s == '0' || *s == '1') { value = value * 2 + (*s++ - '0'); continue; }
			return value;
		}
	}

	//octal (or decimal '0')
	if(x == '0') {
		s += 1;
		for(;;) {
			if(*s >= '0' && *s <= '7') { value = value * 8 + (*s++ - '0'); continue; }
			return value;
		}
	}

	//decimal
	if(x >= '0' && x <= '9') {
		for(;;) {
			if(*s >= '0' && *s <= '9') { value = value * 10 + (*s++ - '0'); continue; }
			return value;
		}
	}

	//char
	if(x == '\'') {
		s += 1;
		value = state.table[*s++];
		if(*s != '\'') throw "mismatched_char";
		s += 1;
		return value;
	}

	throw "nall::bad_eval_integer";
}