@@ -205,26 +205,13 @@ auto BGP::decode(const Data &data, bool enable_as4) -> pjs::Array* {
205
205
206
206
void BGP::encode (pjs::Object *payload, bool enable_as4, Data &data) {
207
207
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);
216
209
217
210
if (auto *body = msg->body .get ()) {
218
211
Data::Builder db (payload_buffer, &s_dp);
219
212
switch (msg->type .get ()) {
220
213
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);
228
215
uint8_t ip[4 ];
229
216
if (!m->identifier || !utils::get_ip_v4 (m->identifier ->str (), ip)) {
230
217
std::memset (ip, 0 , sizeof (ip));
@@ -276,13 +263,7 @@ void BGP::encode(pjs::Object *payload, bool enable_as4, Data &data) {
276
263
}
277
264
278
265
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);
286
267
Data withdrawn, path_addr;
287
268
if (auto *a = m->withdrawnRoutes .get ()) {
288
269
Data::Builder db (withdrawn, &s_dp);
@@ -357,19 +338,27 @@ void BGP::encode(pjs::Object *payload, bool enable_as4, Data &data) {
357
338
}
358
339
359
340
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);
367
342
db.push (uint8_t (m->errorCode ));
368
343
db.push (uint8_t (m->errorSubcode ));
369
344
if (auto *data = m->data .get ()) db.push (*data);
370
345
break ;
371
346
}
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
+ }
373
362
}
374
363
db.flush ();
375
364
}
@@ -435,7 +424,10 @@ auto BGP::Parser::on_state(int state, int c) -> int {
435
424
break ;
436
425
case MessageType::KEEPALIVE:
437
426
break ;
438
- default : error (0 , 0 ); return ERROR;
427
+ case MessageType::ROUTE_REFRESH:
428
+ m_message->body = MessageRouteRefresh::make ();
429
+ break ;
430
+ default : break ;
439
431
}
440
432
if (size > sizeof (m_header)) {
441
433
m_body->clear ();
@@ -461,7 +453,13 @@ auto BGP::Parser::on_state(int state, int c) -> int {
461
453
case MessageType::NOTIFICATION:
462
454
parse_ok = parse_notification (r);
463
455
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 ;
465
463
}
466
464
if (parse_ok) {
467
465
Deframer::need_flush ();
@@ -585,6 +583,23 @@ bool BGP::Parser::parse_notification(Data::Reader &r) {
585
583
return true ;
586
584
}
587
585
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
+
588
603
bool BGP::Parser::error (int code, int subcode) {
589
604
pjs::Ref<MessageNotification> msg (MessageNotification::make (code, subcode));
590
605
on_message_error (msg);
@@ -845,6 +860,7 @@ template<> void EnumDef<BGP::MessageType>::init() {
845
860
define (BGP::MessageType::UPDATE, " UPDATE" );
846
861
define (BGP::MessageType::NOTIFICATION, " NOTIFICATION" );
847
862
define (BGP::MessageType::KEEPALIVE, " KEEPALIVE" );
863
+ define (BGP::MessageType::ROUTE_REFRESH, " ROUTE_REFRESH" );
848
864
}
849
865
850
866
//
@@ -906,7 +922,25 @@ template<> void ClassDef<BGP::PathAttribute>::init() {
906
922
//
907
923
908
924
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
+
910
944
field<Ref<Object>>(" body" , [](BGP::Message *obj) { return &obj->body ; });
911
945
}
912
946
@@ -942,4 +976,13 @@ template<> void ClassDef<BGP::MessageNotification>::init() {
942
976
field<Ref<pipy::Data>>(" data" , [](BGP::MessageNotification *obj) { return &obj->data ; });
943
977
}
944
978
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
+
945
988
} // namespace pjs
0 commit comments