[Click] Error in compiling a new element-Urgent

kunal shah shakuni2 at yahoo.co.in
Wed Nov 30 03:25:35 EST 2005


Hi,

I am getting the following error when I tried to
compile a new element called iptable2(which is lulea
implementation). I have put this element in
elements/ip directory.

My iptable2.cc file is

---------------------------------------------
#include <click/config.h>
#include "iptable2.hh"
#include <click/ipaddress.hh>
#include <click/error.hh>
#include <click/integers.hh>
CLICK_DECLS

#define MT_MAX                   675
#define DIRECT_POINTER  (MT_MAX + 5)            //
arbitrary value > MT_MAX

bool IPTable2::_mt_done = false;
uint8_t IPTable2::_maptable[MT_MAX+1][8];
uint16_t IPTable2::_mask2index[256][256];      // see
build_maptable()

IPTable2::IPTable2()
  : entries(0), dirty(false)
{
  if(!_mt_done)
    build_maptable();
}

IPTable2::~IPTable2()
{
}


// Adds an entry to the simple routing table if not in
there already.
// Allows only one gateway for equals dst/mask
combination.
void
IPTable2::add(unsigned dst, unsigned mask, unsigned
gw)
{
  for(int i = 0; i < _v.size(); i++)
    if(_v[i]._valid && (_v[i]._dst == dst) &&
(_v[i]._mask == mask))
      return;

  struct Entry e;
  e._dst = dst;
  e._mask = mask;
  e._gw = gw;
  e._valid = 1;
  _v.push_back(e);

  entries++;
  dirty = true;
}


// Deletes an entry from the routing table.
void
IPTable2::del(unsigned dst, unsigned mask)
{
  for(int i = 0; i < _v.size(); i++){
    if(_v[i]._valid && (_v[i]._dst == dst) &&
(_v[i]._mask == mask)) {
      _v[i]._valid = 0;
      entries--;
      dirty = true;
      return;
    }
  }
}

// Returns the i-th record.
bool
IPTable2::get(int i, unsigned &dst, unsigned &mask,
unsigned &gw)
{
  assert(i >= 0 && i < _v.size());

  if(i < 0 || i >= _v.size() || _v[i]._valid == 0) {
    dst = mask = gw = 0;
    return(false);
  }

  dst = _v[i]._dst;
  mask = _v[i]._mask;
  gw = _v[i]._gw;
  return(true);
}


// Use the fast routing table to perform the lookup.
bool
IPTable2::lookup(unsigned dst, unsigned &gw, int
&index)
{
  if(!entries)
    return false;

  // Just in time. XXX: Change this to timer.
  if(dirty) {
    build();
    dirty = false;
  }

  // XXX: don't do it this way.
  dst = ntohl(dst);

  uint16_t ix = (dst & 0xfff00000) >> 20;      //
upper 12 bits.
  uint16_t bix = (dst & 0xffc00000) >> 22;     //
upper 10 bits.
  uint8_t bit = (dst & 0x000f0000) >> 16;      //
lower  4 of upper 16 bits.
  uint16_t codeword = codewords1[ix];
  uint16_t ten = (codeword & 0xffc0) >> 6;     //
upper 10 bits.
  uint8_t six = codeword & 0x003f;             //
lower  6 bits.

  // Offset is not offset but pointer to routing
table. See 4.2.1 of Degermark.
  if(ten == DIRECT_POINTER) {
    index = six;
    goto done;
  }

  // Figure 10 in Degermark is wrong.
  int offset = _maptable[ten][bit >> 1];
  if(bit & 0x0001) // odd
    offset &= 0x0f;
  else
    offset >>= 4;
  uint16_t pix = baseindex1[bix] + six + offset;
  index = l1ptrs[pix];

done:
  gw = _v[index & 0x3fff]._gw;
  return(true);
}

// Builds the whole structure as described by the
Lulea Algorithm.
// After execution l1ptrs, codewords1 and baseindex1
represent routing table.
//
// (NOT FINISHED: level 2 and 3)
//
// bitvector1 contains bitvector as described in
section 4.2 of Degermark.
// bit_admin contains an entry for each bit in
bitvector1.
// Both are temporary.
void
IPTable2::build()
{
  uint16_t bitvector1[4096];
  struct bit bit_admin[65536];

  for(register int i = 0; i < 65536; i++)
    bit_admin[i].from_level = bit_admin[i].value = 0;
  for(register int i = 0; i < 4096; i++)
    codewords1[i] = bitvector1[i] = 0;
  for(register int i = 0; i < 1024; i++)
    baseindex1[i] = 0;
  l1ptrs.clear();

  Vector<int> affected;
  for(int i = 0; i < entries; i++) {
    if(_v[i]._valid == 0)
      continue;

    // masked, high16, dst, mask and 0x0000ffff in
network order!
    // masked == (IP address range from router table)
    uint32_t masked = (_v[i]._dst & _v[i]._mask);
    uint16_t high16 = masked & 0x0000ffff;
    if(high16 == 0)
      continue;
    high16 = ntohs(high16);

    // click_chatter("Inserting %x", high16);
    // set bits in bitvector for this routing table
entry
    affected.clear();
    set_all_bits(bitvector1, bit_admin, high16, i,
affected);

    // For all affected shorts in bitvector, check
whether or not they are
    // 0 or 1 and if so apply the optimization
described in section 4.2.1 of
    // Degermark.
    uint16_t bv;
    int af_index;
    for(int j = 0; j < affected.size(); j++) {
      af_index = affected[j];
      bv = bitvector1[af_index];
      if(!(bv & 0xfffe)) { // bv == 0 || bv == 1
        codewords1[af_index] = ((DIRECT_POINTER) <<
6);
        codewords1[af_index] += i;
      }
    }
  }

  // Now build l1ptrs, based on set bits in
bitvector1. See section 4.2 of
  // Degermark.
  for(register int i = 0; i < 65536; i++)
    if(bit_admin[i].value) {
      l1ptrs.push_back(bit_admin[i].value);
      // click_chatter("Pushed bit %d (== %x) on
vector (index = %d) : %x", i, bit_admin[i].value,
l1ptrs.size()-1, l1ptrs[l1ptrs.size()-1]);
    }


  // First entry of baseindex1 always 0.
  int bi1_idx = 0;
  baseindex1[bi1_idx++] = 0;

  int mt_index = 0, bits_so_far = 0;
  for(int j = 0; j < 4096; j++) {
    uint16_t bv = bitvector1[j];
    // click_chatter("bitvector1[%d] = %x", j,
bitvector1[j]);

    // Write record-index of maptable in upper 10
bits. No such index exists
    // for records where bv == 0 or bv == 1 (see
section 4.2.1).
    if(bv & 0xfffe) { // if (bv != 0x0000 && bv !=
0x0001)
      mt_index = mt_indexfind(bitvector1[j]);
      codewords1[j] = mt_index << 6;
    }

    // Lower 6 bits of codewords contain offset. Every
fourth codeword starts
    // with offset 0.
    //
    // For codewords related to a bv == 0 or bv == 1,
there might be direct
    // routing table index in the related codeword
(section 4.2.1). Don't
    // overwrite that entry.

    // Every non 4th codeword.
    if(j & 0x0003) {
      if(((codewords1[j] & 0xffc0) >> 6) !=
DIRECT_POINTER) {
        codewords1[j] += bits_so_far;
      }
      // else {
      //   this means that related bv == 0 or bv == 1
      // }


    // Every 4th codeword: 0 and set baseindex.
    } else if(j) {
      baseindex1[bi1_idx] = baseindex1[bi1_idx-1] +
bits_so_far;
      // click_chatter("baseindex1[%d] = %d", bi1_idx,
baseindex1[bi1_idx]);
      bi1_idx++;
      bits_so_far = 0;
    }

    // Raise bits_so_far.

    // The number of bits in a short from the
bitvector can be retrieved from
    // maptable, although we still have to check for
the most sign. bit since
    // maptable only tells the # of set bits BEFORE
the x-th bit.
    //
    // For bv == 0 or bv == 1 there is no maptable
entry. Just check.
    if(bv & 0xfffe) // bv != 0x0000 && bv != 0x0001
      bits_so_far += ((_maptable[mt_index][7] & 0x0f)
+ ((bv & 0x8000) ? 1 : 0));
    else
      bits_so_far += (bv & 0x0001);

    // click_chatter("codewords1[%d] is %x", j,
codewords1[j]);
  }
}




// Sets all necessary bits in bitvector based on a
(part of a) IP address. Read
// section 4.2 of Degermark to see which bits are set
and what they mean.
//
// bitvector    - bitvector as described in 4.2 of
Degermark
// bit_admin    - table to temp. store info on each
bit in bitvector
// high16       - 16 most sign. bits of IP address
// rtable_idx   - index in sorted routing table where
high16 came from
// affected     - vector with indices of altered
shorts in bitvector
void
IPTable2::set_all_bits(uint16_t bitvector[],
                       struct bit bit_admin[],
                       uint16_t high16,
                       int rtable_idx,
                       Vector<int> &affected)
{
  uint16_t value;

  uint16_t headinfo = (NEXT_HOP | rtable_idx);
  for(int i = 0; i < 16; i++) {
    value = high16 >> (15-i);

    // Every node must have 0 or 2 children. Every
node has to set a 1 in the
    // bitvector where its range starts. See Degermark
figure 5.
    if(value & 0x0001)
      set_single_bit(bitvector, bit_admin, i, 16,
(value >> 1), headinfo, affected);
    else
      set_single_bit(bitvector, bit_admin, i+1, 16,
value | 0x0001, headinfo, affected);
  }

  // click_chatter("Setting bit on level 16");
  uint16_t masked = _v[rtable_idx]._dst &
_v[rtable_idx]._mask;
  headinfo = (((masked & 0xffff0000) ? CHUNK :
NEXT_HOP) | rtable_idx);
  set_single_bit(bitvector, bit_admin, 16, 16, value,
headinfo, affected);
  return;
}



// Sets a single bit in the supplied bitvector.
//
// See section 4. What Degermark doesn't tell you is
that expanding the prefix
// tree to be complete causes annoying collisions of
bits in the bitvector:
// different entries of the routing table might try to
set the same bit in the
// bitvector. A node closest to the bitvector can
override bits set by nodes
// further away from the bitvector. Figure 4
illustrates this (the two rightmost
// nodes; e2 'hides' entries of e1. e2 can do this
because it is closer to the
// bitvector).
//
// bitvector    - where bit has to be set
// bit_admin    - contains info on what entry caused
which bit to be set.
// from_level   - since prefix tree is complete, every
node at whatever level
// can cause a bit to be set down in the bitvector.
From_level tells this method
// from which level this bit is set. Later needed to
see who can override other
// ones bits.
//
// to_level     - 16 for level 1, 24 for level 2, 32
for level 3.
// value        - The prefix of an IP address. The
number of relevant bits
// equals from_level.
//
// headinfo     - The headinfo to be placed in l1ptrs
in a later phase.
inline void
IPTable2::set_single_bit(uint16_t bitvector[],
                         struct bit bit_admin[],
                         uint32_t from_level,
                         uint32_t to_level,
                         uint32_t value,
                         uint16_t headinfo,
                         Vector<int> &affected)
{
  assert(from_level <= to_level);
  unsigned int leveldiff = to_level - from_level;
  unsigned bit_in_vector = value << leveldiff;
  int vector_index = bit_in_vector >> 4;
  int bit_in_short = bit_in_vector & 0x000f;

  // Only override set bit if it is set from a lower
level in prefix tree.
  if(bitvector[vector_index] & (0x0001 <<
bit_in_short))
    if(bit_admin[bit_in_vector].from_level >=
from_level)
      return;
  bitvector[vector_index] |= (0x0001 << bit_in_short);
  bit_admin[bit_in_vector].value = headinfo;
  bit_admin[bit_in_vector].from_level = from_level;
  affected.push_back(vector_index);

  // click_chatter("bitvector[%d] is %x",
vector_index, bitvector[vector_index]);
}




// Returns the index in _maptable where mask can be
found.
inline uint16_t
IPTable2::mt_indexfind(uint16_t mask)
{
  assert(mask != 0x0000 && mask != 0x0001);
  return _mask2index[mask >> 8][mask & 0x00ff];
}



// Builds maptable as described by Degermark.
void
IPTable2::build_maptable()
{
  uint8_t set_bits;
  uint16_t mask;

  Vector<uint16_t> masks = all_masks(4, true);
  assert(masks.size() == MT_MAX + 1);

  for(int i = 0; i < masks.size(); i++) {
    mask = masks[i];
    _maptable[i][0] = set_bits = 0;
    for(uint8_t j = 1; j < 16; j++) {
      if(mask & 0x0001)
        set_bits++;
      mask >>= 1;

      // j even: set upper 4 bits.
      if((j & 0x0001) == 0)
        _maptable[i][j >> 1] = (set_bits << 4);
      else
        _maptable[i][j >> 1] |= set_bits;
    }
  }

  _mt_done = true;
}

// Generates all possible masks of length 2^length AND
a mapping from these
// See section 4.2 formula (2).
//
// _mask2index is a two-dimensional array that
translates masks to the index in
// maptable related to that mask.
Vector<uint16_t>
IPTable2::all_masks(int length, bool toplevel)
{
  assert(length >= 0 && length <= 4);

  Vector<uint16_t> v;
  if(length == 0) {
    v.push_back(0x0001);
    return v;
  }

  v = all_masks(length-1, false);

  // Create the shifted version of all of masks in v.
  Vector<uint16_t> shifted_v;
  for(int i = 0; i < v.size(); i++)
    shifted_v.push_back(v[i] << (0x0001 <<
(length-1)));

  // On toplevel, don't put 1 in there. See section
4.2.1
  Vector<uint16_t> v_new;
  if(!toplevel)
    v_new.push_back(0x0001);

  // Create all masks of length 2^length.
  int mt_index = 0;
  for(int i = 0; i < shifted_v.size(); i++) {
    for(int j = 0; j < v.size(); j++) {
      uint16_t mask = shifted_v[i] | v[j];
      v_new.push_back(mask);
      if(toplevel) {
         // click_chatter("Record %d is for mask %x",
mt_index, mask);
        _mask2index[mask >> 8][mask & 0x00ff] =
mt_index++;
      }
    }
  }

  return v_new;
}

int
IPTable2::configure(Vector<String> &conf, ErrorHandler
*errh)
{
    click_chatter("I am in configure of Lulea");
    int before = errh->nerrors();
    IPRoute r;
    for (int i = 0; i < conf.size(); i++) {
/*        if (cp_ip_route_lulea(conf[i], &r, false,
this)
            && r.port >= 0 && r.port < noutputs())
            (void) add(r.addr.addr(), r.mask.addr(),
r.gw.addr());
        else
            errh->error("argument %d should be
'ADDR/MASK [GATEWAY] OUTPUT'", i+1);*/
    }

    return (errh->nerrors() != before ? -1 : 0);
}

void
IPTable2::push(int, Packet *p)
{
/*    IPAddress gw;
    int port = lookup(p->dst_ip_anno(), gw);
    if (port >= 0) {
        assert(port < noutputs());
        if (gw)
            p->set_dst_ip_anno(gw);
        output(port).push(p);
    } else {
        static int complained = 0;
        if (++complained <= 5)
            click_chatter("IPRouteTable: no route for
%s", p->dst_ip_anno().s().c_str());
        p->kill();
    }*/
}

/*bool
IPTable2::cp_ip_route_lulea(String s, IPRoute
*r_store, bool remove_route, Element *context)
{
    IPRoute r;
    if (!cp_ip_prefix(cp_pop_spacevec(s), &r.addr,
&r.mask, true, context))
        return false;
    r.addr &= r.mask;

    String word = cp_pop_spacevec(s);
    if (word == "-")
        // null gateway; do nothing
    else if (cp_ip_address(word, &r.gw, context))
        // do nothing
    else
        goto two_words;

    word = cp_pop_spacevec(s);
  two_words:
    if (cp_integer(word, &r.port) || (!word &&
remove_route))
        if (!cp_pop_spacevec(s)) { // nothing left
            *r_store = r;
           return true;
        }

    return false;
}*/

// generate Vector template instance
#include <lib/vectorv.cc>
//template class Vector<IPTable2::Entry>;
CLICK_ENDDECLS
ELEMENT_PROVIDES(IPTable2)
EXPORT_ELEMENT(IPTable2)

-------------------------------------------------- 

This is the error I am getting :-

----------------------------------------
[root at gregario click]# make install
make[1]: Entering directory `/root/click/userlevel'
g++ -W -Wall -fno-exceptions -fno-rtti 
-DHAVE_CONFIG_H -I../include -I../include -I. -I.. 
-DCLICK_USERLEVEL -g -O2 -MD -c
../elements/ip/iptable2.cc
../elements/ip/iptable2.cc:460: warning: unused
parameter ‘p’
../elements/ip/iptable2.cc:510: error: expected
class-name at end of input
make[1]: *** [iptable2.o] Error 1
make[1]: Leaving directory `/root/click/userlevel'
make: *** [install] Error 1
----------------------------------------------

Please advise. 

Thanks
Kunal




		
__________________________________________________________ 
Enjoy this Diwali with Y! India Click here http://in.promos.yahoo.com/fabmall/index.html


More information about the click mailing list