Skip to content

Commit

Permalink
bier: Add BFR prefix to BIFT
Browse files Browse the repository at this point in the history
  • Loading branch information
nrybowski committed Oct 31, 2024
1 parent b505da5 commit f57049c
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 22 deletions.
7 changes: 5 additions & 2 deletions elements/bier/bierroutetable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <click/error.hh>
#include <click/glue.hh>
#include <click/ip6address.hh>
#include <click/ipaddress.hh>
CLICK_DECLS

void* BierRouteTable::cast(const char *name) {
Expand All @@ -30,7 +31,7 @@ void* BierRouteTable::cast(const char *name) {
return Element::cast(name);
}

int BierRouteTable::add_route(bfrid, bitstring, IP6Address, int, String, ErrorHandler *errh) {
int BierRouteTable::add_route(bfrid, IP6Address, bitstring, IP6Address, int, String, ErrorHandler *errh) {
return errh->error("cannot add routes to this routing table");
}

Expand All @@ -44,6 +45,7 @@ int BierRouteTable::add_route_handler(const String &conf, Element *e, void *, Er
cp_spacevec(conf, words);

bfrid dst;
IP6Address bfr_prefix;
bitstring fbm;
IP6Address nxt;
int output;
Expand All @@ -54,14 +56,15 @@ int BierRouteTable::add_route_handler(const String &conf, Element *e, void *, Er
// TODO: read_all for BFRID and define dst as an array for route addition batching
ok = Args(words, r, errh)
.read_mp("BFRID", dst)
.read_mp("BFRPREFIX", bfr_prefix)
.read_mp("BITSTRING", fbm)
.read_mp("NXT", nxt)
.read_mp("IFIDX", output)
.read_mp("IFNAME", ifname)
.complete();

if (ok >= 0)
ok = r->add_route(dst, fbm, nxt, output, ifname, errh);
ok = r->add_route(dst, bfr_prefix, fbm, nxt, output, ifname, errh);

return ok;
}
Expand Down
2 changes: 1 addition & 1 deletion elements/bier/bierroutetable.hh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class BierRouteTable : public BatchElement {
void* cast(const char*) override;
const char *port_count() const override { return PORTS_0_0; }

virtual int add_route(bfrid, bitstring, IP6Address, int, String, ErrorHandler*);
virtual int add_route(bfrid, IP6Address, bitstring, IP6Address, int, String, ErrorHandler*);
virtual String dump_routes();

static int add_route_handler(const String&, Element*, void*, ErrorHandler*);
Expand Down
26 changes: 15 additions & 11 deletions elements/bier/lookupbiertable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <click/config.h>
#include <click/args.hh>
#include <click/glue.hh>
#include <click/ip6address.hh>
#include <click/packet.hh>
#include <click/straccum.hh>
#include <clicknet/bier.h>
Expand Down Expand Up @@ -72,7 +73,7 @@ int LookupBierTable::classify(Packet *p_in) {

unsigned short k = 0;
uint16_t bift_id;
IP6Address nxt;
IP6Address nxt, bfr_prefix;
bitstring fbm;
bfrid bfr_id;
int index;
Expand Down Expand Up @@ -106,7 +107,10 @@ int LookupBierTable::classify(Packet *p_in) {
);

// Sanity check: the BIFT ID specified in the BIER packet corresponds to the current BIFT.
if (bier->bier_bift_id != _bift_id) return -1;
if (bier->bier_bift_id != _bift_id) {
click_chatter("Unknown BIFT-ID %x. Ignoring.", bier->bier_bift_id);
return -1;
}

// RFC8279 Section 6.5 Step 2
while (bs != 0) {
Expand Down Expand Up @@ -134,20 +138,20 @@ int LookupBierTable::classify(Packet *p_in) {
// the BIER packet's BIFT ID already has been verified earlier.

// RFC8279 Section 6.5 Step 6
if (_t.lookup(bfr_id, fbm, nxt, index, ifname)) {
if (_t.lookup(bfr_id, bfr_prefix, fbm, nxt, index, ifname)) {
fbm.resize(bsl);

// RFC8279 Section 6.5 Step 7
WritablePacket *p2 = p->duplicate();
SET_DST_IP6_ANNO(p2, nxt);
click_ip6 *ip6 = reinterpret_cast<click_ip6*>(p2->data());
ip6->ip6_dst = nxt;
click_bier *bier_dup = reinterpret_cast<click_bier*>(p2->data()+sizeof(click_ip6));
memcpy(bier_dup->bitstring, (bs & fbm).data_words(), bsl/(sizeof(Bitvector::word_type)*8));
bier_dup->encode();
// TODO: Add ethernet header to the packet
ip6->ip6_dst = bfr_prefix;
click_bier *bier = reinterpret_cast<click_bier*>(p2->data()+sizeof(click_ip6));
memcpy(bier->bitstring, (bs & fbm).data_words(), bsl/(sizeof(Bitvector::word_type)*8));
bier->encode();

// ifname is ensured to be in _ifaces because of the check upon route addition.
output(_ifaces[ifname]).push(p2->duplicate());
output(_ifaces[ifname]).push(p2);

// RFC8279 Section 6.5 Step 8
bs &= ~fbm;
Expand All @@ -165,11 +169,11 @@ int LookupBierTable::classify(Packet *p_in) {
return -1;
}

int LookupBierTable::add_route(bfrid dst, bitstring fbm, IP6Address nxt, int output, String ifname, ErrorHandler *errh) {
int LookupBierTable::add_route(bfrid dst, IP6Address bfr_prefix, bitstring fbm, IP6Address nxt, int output, String ifname, ErrorHandler *errh) {
// if (output < 0 || output >= noutputs())
// return errh->error("port number <%u> out of range", output);
// TODO: Check if ifname is in table
_t.add(dst, fbm, nxt, output, ifname);
_t.add(dst, bfr_prefix, fbm, nxt, output, ifname);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion elements/bier/lookupbiertable.hh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class LookupBierTable : public ClassifyElement<LookupBierTable, BierRouteTable>
int configure(Vector<String> &, ErrorHandler *) CLICK_COLD;
void add_handlers() override CLICK_COLD;

int add_route(bfrid dst, bitstring fbm, IP6Address nxt, int, String, ErrorHandler*);
int add_route(bfrid dst, IP6Address bfr_prefix, bitstring fbm, IP6Address nxt, int, String, ErrorHandler*);
String dump_routes() { return _t.dump(); }

private:
Expand Down
5 changes: 3 additions & 2 deletions include/click/biertable.hh
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ class BierTable {
BierTable();
~BierTable();

bool lookup(const bfrid &dst, bitstring &fbm, IP6Address &nxt, int &index, String &ifname) const;
bool lookup(const bfrid &dst, IP6Address &bfr_prefix, bitstring &fbm, IP6Address &nxt, int &index, String &ifname) const;

void del(const bfrid &dst);
void add(const bfrid &dst, const bitstring fbm, const IP6Address &nxt, int output, String ifname);
void add(const bfrid &dst, const IP6Address bfr_prefix, const bitstring fbm, const IP6Address &nxt, int output, String ifname);
void clear() { _v.clear(); }
String dump();

private:
struct Entry {
bfrid _dst;
IP6Address _bfr_prefix;
bitstring _fbm;
IP6Address _nxt;
int _if_idx;
Expand Down
8 changes: 6 additions & 2 deletions include/clicknet/bier.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,22 @@ struct click_bier {
bier_un.bier_un1.bier_un1_l3 = htonl(bier_un.bier_un1.bier_un1_l3);
// FIXME: Do not use BSL per RFC8296. BSL should be provided as an argument.
size_t bsl = _click_bier_expand_bsl(bier_bsl) / 32;
click_chatter("bsl %u %u", bier_bsl, bsl);
uint32_t _bitstring[bsl] = {0};
uint32_t _bitstring[bsl];
for (size_t i=0; i<bsl; i++) _bitstring[bsl-1-i] = htonl(bitstring[i]);
memcpy(bitstring, _bitstring, bsl*sizeof(uint32_t));
#endif
}

void encode() {
#if CLICK_BYTE_ORDER == CLICK_LITTLE_ENDIAN
// FIXME: Do not use BSL per RFC8296. BSL should be provided as an argument.
size_t bsl = _click_bier_expand_bsl(bier_bsl) / 32;
bier_un.bier_un1.bier_un1_l1 = ntohl(bier_un.bier_un1.bier_un1_l1);
bier_un.bier_un1.bier_un1_l2 = ntohl(bier_un.bier_un1.bier_un1_l2);
bier_un.bier_un1.bier_un1_l3 = ntohl(bier_un.bier_un1.bier_un1_l3);
uint32_t _bitstring[bsl];
for (size_t i=0; i<bsl; i++) _bitstring[bsl-1-i] = ntohl(bitstring[i]);
memcpy(bitstring, _bitstring, bsl*sizeof(uint32_t));
#endif
}

Expand Down
9 changes: 6 additions & 3 deletions lib/biertable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ CLICK_DECLS
BierTable::BierTable(){}
BierTable::~BierTable(){}

bool BierTable::lookup(const bfrid &dst, bitstring &fbm, IP6Address &nxt, int &index, String &ifname) const {
bool BierTable::lookup(const bfrid &dst, IP6Address &bfr_prefix, bitstring &fbm, IP6Address &nxt, int &index, String &ifname) const {
int best = -1;

for (int i = 0; i < _v.size(); i++) {
Expand All @@ -39,6 +39,7 @@ bool BierTable::lookup(const bfrid &dst, bitstring &fbm, IP6Address &nxt, int &i
return false;
else {
nxt = _v[best]._nxt;
bfr_prefix = _v[best]._bfr_prefix;
fbm = _v[best]._fbm;
index = _v[best]._if_idx;
ifname = _v[best]._if_name;
Expand All @@ -53,9 +54,10 @@ void BierTable::del(const bfrid &dst) {
}
}

void BierTable::add(const bfrid &dst, const bitstring fbm, const IP6Address &nxt, int output, String ifname) {
void BierTable::add(const bfrid &dst, const IP6Address bfr_prefix, const bitstring fbm, const IP6Address &nxt, int output, String ifname) {
struct Entry e;
e._dst = dst;
e._bfr_prefix = bfr_prefix;
e._fbm = fbm;
e._nxt = nxt;
e._valid = 1;
Expand All @@ -76,10 +78,11 @@ void BierTable::add(const bfrid &dst, const bitstring fbm, const IP6Address &nxt
String BierTable::dump() {
StringAccum sa;
if (_v.size())
sa << "# Active routes\n# BFR-id F-BM Nexthop Ifindex\n";
sa << "# Active routes\n# BFR-id BFR-prefix F-BM Nexthop Ifindex\n";
for (int i=0; i< _v.size(); i++) {
if (_v[i]._valid) {
sa << " " << _v[i]._dst;
sa << " " << _v[i]._bfr_prefix;
sa << " " << _v[i]._fbm.unparse();
sa << " " << _v[i]._nxt;
sa << " " << _v[i]._if_idx;
Expand Down

0 comments on commit f57049c

Please sign in to comment.