[Click] Error in compiling a new element-Urgent

Frederic Van Quickenborne frederic.vanquickenborne at intec.ugent.be
Wed Nov 30 09:47:34 EST 2005


Hi,

maybe you can try to put this at the end of the file:

#include <lib/vectorv.cc>
template class Vector<int>;
template class Vector<uint16_t>;
CLICK_ENDDECLS
ELEMENT_PROVIDES(IPTable2)
EXPORT_ELEMENT(IPTable2)


Let us know if it helps you,
Frederic.

kunal shah wrote:

>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
>_______________________________________________
>click mailing list
>click at amsterdam.lcs.mit.edu
>https://amsterdam.lcs.mit.edu/mailman/listinfo/click
>
>  
>

-- 
Frederic Van Quickenborne
Department of Information Technology (INTEC)
Ghent University - IBBT - IMEC
Gaston Crommenlaan 8 (Bus 201), B-9050 Gent, Belgium
tel.: +32-9331 4974; tel. secr.: +32-9331 4900
fax: +32-9331 4899
Frederic.VanQuickenborne at intec.ugent.be
http://www.ibcn.intec.ugent.be

The contents of this e-mail are intended for the named addressee(s) only. It contains information which may be confidential and which may also be privileged. Unless you are the named addressee (or authorised to receive for the addressee) you may not copy or use it, or disclose it to anyone else. If you received it in error please notify us immediately and then destroy it. Further, we make every effort to keep our network free from viruses. However, you do need to check this e-mail and any attachments to it for viruses as we can take no responsibility for any computer virus which might be transferred by way of this e-mail.





More information about the click mailing list