Skip to content

Commit ba28e1d

Browse files
committed
[filter] Added BGP message type ROUTE_REFRESH
1 parent 737ff0a commit ba28e1d

File tree

5 files changed

+105
-36
lines changed

5 files changed

+105
-36
lines changed

samples/bgp/config-example.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
as: 1234
2-
id: 127.17.0.1
2+
id: 172.17.0.1
33
peers:
44
- 172.17.0.2
55
ipv4:

samples/bgp/main.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var isExiting = false
88
var $peer
99

1010
var session = pipeline($=>$
11-
.mux(() => $peer).to($=>$
11+
.mux(() => $peer, { maxQueue: 0 }).to($=>$
1212
.encodeBGP({ enableAS4: () => $peer.isAS4() })
1313
.handleMessage(msg => console.debug('>>>', $peer.state(), msg.payload))
1414
.connect(() => $peer.destination, { idleTimeout: 0 })

samples/bgp/peer.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export default function (config, address) {
22

33
var AS_TRANS = 23456
4-
var MY_AS = config.as
4+
var MY_AS = Number.parseInt(config.as)
55
var BGP_IDENTIFIER = config.id
66
var HOLD_TIME = (holdTime in config ? config.holdTime : 90)
77
var IPV4_NEXT_HOP = os.env.BGP_SPEAKER_IPV4_NEXTHOP || config.ipv4.nextHop
@@ -170,6 +170,11 @@ export default function (config, address) {
170170
code: 1,
171171
value: new Data([0, 2, 0, 1]),
172172
},
173+
{
174+
// Route Refresh Capability
175+
code: 2,
176+
value: new Data,
177+
},
173178
{
174179
// Graceful Restart Capability
175180
code: 64,

src/api/bgp.cpp

+76-33
Original file line numberDiff line numberDiff line change
@@ -205,26 +205,13 @@ auto BGP::decode(const Data &data, bool enable_as4) -> pjs::Array* {
205205

206206
void BGP::encode(pjs::Object *payload, bool enable_as4, Data &data) {
207207
Data payload_buffer;
208-
209-
pjs::Ref<Message> msg;
210-
if (payload && payload->is<Message>()) {
211-
msg = payload->as<Message>();
212-
} else {
213-
msg = Message::make();
214-
if (payload) pjs::class_of<Message>()->assign(msg, payload);
215-
}
208+
pjs::Ref<Message> msg = pjs::coerce<Message>(payload);
216209

217210
if (auto *body = msg->body.get()) {
218211
Data::Builder db(payload_buffer, &s_dp);
219212
switch (msg->type.get()) {
220213
case MessageType::OPEN: {
221-
pjs::Ref<MessageOpen> m;
222-
if (body->is<MessageOpen>()) {
223-
m = body->as<MessageOpen>();
224-
} else {
225-
m = MessageOpen::make();
226-
pjs::class_of<MessageOpen>()->assign(m, body);
227-
}
214+
pjs::Ref<MessageOpen> m = pjs::coerce<MessageOpen>(body);
228215
uint8_t ip[4];
229216
if (!m->identifier || !utils::get_ip_v4(m->identifier->str(), ip)) {
230217
std::memset(ip, 0, sizeof(ip));
@@ -276,13 +263,7 @@ void BGP::encode(pjs::Object *payload, bool enable_as4, Data &data) {
276263
}
277264

278265
case MessageType::UPDATE: {
279-
pjs::Ref<MessageUpdate> m;
280-
if (body->is<MessageUpdate>()) {
281-
m = body->as<MessageUpdate>();
282-
} else {
283-
m = MessageUpdate::make();
284-
pjs::class_of<MessageUpdate>()->assign(m, body);
285-
}
266+
pjs::Ref<MessageUpdate> m = pjs::coerce<MessageUpdate>(body);
286267
Data withdrawn, path_addr;
287268
if (auto *a = m->withdrawnRoutes.get()) {
288269
Data::Builder db(withdrawn, &s_dp);
@@ -357,19 +338,27 @@ void BGP::encode(pjs::Object *payload, bool enable_as4, Data &data) {
357338
}
358339

359340
case MessageType::NOTIFICATION: {
360-
pjs::Ref<MessageNotification> m;
361-
if (body->is<MessageNotification>()) {
362-
m = body->as<MessageNotification>();
363-
} else {
364-
m = MessageNotification::make();
365-
pjs::class_of<MessageNotification>()->assign(m, body);
366-
}
341+
pjs::Ref<MessageNotification> m = pjs::coerce<MessageNotification>(body);
367342
db.push(uint8_t(m->errorCode));
368343
db.push(uint8_t(m->errorSubcode));
369344
if (auto *data = m->data.get()) db.push(*data);
370345
break;
371346
}
372-
default: break;
347+
348+
case MessageType::ROUTE_REFRESH: {
349+
pjs::Ref<MessageRouteRefresh> m = pjs::coerce<MessageRouteRefresh>(body);
350+
db.push(uint16_t(m->afi));
351+
db.push(uint8_t(0));
352+
db.push(uint8_t(m->safi));
353+
break;
354+
}
355+
356+
default: {
357+
if (body->is<Data>()) {
358+
db.push(*body->as<Data>());
359+
}
360+
break;
361+
}
373362
}
374363
db.flush();
375364
}
@@ -435,7 +424,10 @@ auto BGP::Parser::on_state(int state, int c) -> int {
435424
break;
436425
case MessageType::KEEPALIVE:
437426
break;
438-
default: error(0, 0); return ERROR;
427+
case MessageType::ROUTE_REFRESH:
428+
m_message->body = MessageRouteRefresh::make();
429+
break;
430+
default: break;
439431
}
440432
if (size > sizeof(m_header)) {
441433
m_body->clear();
@@ -461,7 +453,13 @@ auto BGP::Parser::on_state(int state, int c) -> int {
461453
case MessageType::NOTIFICATION:
462454
parse_ok = parse_notification(r);
463455
break;
464-
default: break;
456+
case MessageType::ROUTE_REFRESH:
457+
parse_ok = parse_route_refresh(r);
458+
break;
459+
default:
460+
m_message->body = Data::make(*m_body);
461+
parse_ok = true;
462+
break;
465463
}
466464
if (parse_ok) {
467465
Deframer::need_flush();
@@ -585,6 +583,23 @@ bool BGP::Parser::parse_notification(Data::Reader &r) {
585583
return true;
586584
}
587585

586+
bool BGP::Parser::parse_route_refresh(Data::Reader &r) {
587+
auto *body = m_message->body->as<MessageRouteRefresh>();
588+
589+
uint16_t afi;
590+
uint8_t reserved;
591+
uint8_t safi;
592+
593+
if (!read(r, afi)) return false;
594+
if (!read(r, reserved)) return false;
595+
if (!read(r, safi)) return false;
596+
597+
body->afi = afi;
598+
body->safi = safi;
599+
600+
return true;
601+
}
602+
588603
bool BGP::Parser::error(int code, int subcode) {
589604
pjs::Ref<MessageNotification> msg(MessageNotification::make(code, subcode));
590605
on_message_error(msg);
@@ -845,6 +860,7 @@ template<> void EnumDef<BGP::MessageType>::init() {
845860
define(BGP::MessageType::UPDATE, "UPDATE");
846861
define(BGP::MessageType::NOTIFICATION, "NOTIFICATION");
847862
define(BGP::MessageType::KEEPALIVE, "KEEPALIVE");
863+
define(BGP::MessageType::ROUTE_REFRESH, "ROUTE_REFRESH");
848864
}
849865

850866
//
@@ -906,7 +922,25 @@ template<> void ClassDef<BGP::PathAttribute>::init() {
906922
//
907923

908924
template<> void ClassDef<BGP::Message>::init() {
909-
field<EnumValue<BGP::MessageType>>("type", [](BGP::Message *obj) { return &obj->type; });
925+
accessor("type",
926+
[](Object *obj, Value &ret) {
927+
auto t = obj->as<BGP::Message>()->type;
928+
auto s = EnumDef<BGP::MessageType>::name(t);
929+
if (!s) {
930+
ret.set((int)t);
931+
} else {
932+
ret.set(s);
933+
}
934+
},
935+
[](Object *obj, const Value &val) {
936+
if (val.is_string()) {
937+
obj->as<BGP::Message>()->type = EnumDef<BGP::MessageType>::value(val.s());
938+
} else {
939+
obj->as<BGP::Message>()->type = (BGP::MessageType)val.to_int32();
940+
}
941+
}
942+
);
943+
910944
field<Ref<Object>>("body", [](BGP::Message *obj) { return &obj->body; });
911945
}
912946

@@ -942,4 +976,13 @@ template<> void ClassDef<BGP::MessageNotification>::init() {
942976
field<Ref<pipy::Data>>("data", [](BGP::MessageNotification *obj) { return &obj->data; });
943977
}
944978

979+
//
980+
// BGP::MessageRouteRefresh
981+
//
982+
983+
template<> void ClassDef<BGP::MessageRouteRefresh>::init() {
984+
field<int>("afi", [](BGP::MessageRouteRefresh *obj) { return &obj->afi; });
985+
field<int>("safi", [](BGP::MessageRouteRefresh *obj) { return &obj->safi; });
986+
}
987+
945988
} // namespace pjs

src/api/bgp.hpp

+21
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class BGP : public pjs::ObjectTemplate<BGP> {
5252
UPDATE = 2,
5353
NOTIFICATION = 3,
5454
KEEPALIVE = 4,
55+
ROUTE_REFRESH = 5,
5556
};
5657

5758
//
@@ -166,6 +167,25 @@ class BGP : public pjs::ObjectTemplate<BGP> {
166167
friend class pjs::ObjectTemplate<MessageNotification>;
167168
};
168169

170+
171+
//
172+
// BGP::MessageRouteRefresh
173+
//
174+
175+
class MessageRouteRefresh : public pjs::ObjectTemplate<MessageRouteRefresh> {
176+
public:
177+
int afi = 0;
178+
int safi = 0;
179+
180+
private:
181+
MessageRouteRefresh() {}
182+
MessageRouteRefresh(int af, int saf)
183+
: afi(af)
184+
, safi(saf) {}
185+
186+
friend class pjs::ObjectTemplate<MessageRouteRefresh>;
187+
};
188+
169189
//
170190
// BGP::Parser
171191
//
@@ -205,6 +225,7 @@ class BGP : public pjs::ObjectTemplate<BGP> {
205225
bool parse_open(Data::Reader &r);
206226
bool parse_update(Data::Reader &r);
207227
bool parse_notification(Data::Reader &r);
228+
bool parse_route_refresh(Data::Reader &r);
208229
bool error(int code, int subcode);
209230

210231
bool read(Data::Reader &r, Data &data, size_t size);

0 commit comments

Comments
 (0)