1use bytes::{Buf, BufMut, Bytes};
18use std::net::{Ipv4Addr, Ipv6Addr};
19
20use crate::capability::{Afi, Safi};
21use crate::constants::orf;
22use crate::error::DecodeError;
23use crate::nlri::{Ipv4Prefix, Ipv6Prefix, Prefix};
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28pub enum OrfType {
29 AddressPrefix,
31 AddressPrefixLegacy,
33 Unknown(u8),
35}
36
37impl OrfType {
38 #[must_use]
40 pub fn from_u8(value: u8) -> Self {
41 match value {
42 orf::TYPE_ADDRESS_PREFIX => Self::AddressPrefix,
43 orf::TYPE_ADDRESS_PREFIX_LEGACY => Self::AddressPrefixLegacy,
44 other => Self::Unknown(other),
45 }
46 }
47
48 #[must_use]
50 pub fn as_u8(self) -> u8 {
51 match self {
52 Self::AddressPrefix => orf::TYPE_ADDRESS_PREFIX,
53 Self::AddressPrefixLegacy => orf::TYPE_ADDRESS_PREFIX_LEGACY,
54 Self::Unknown(value) => value,
55 }
56 }
57
58 #[must_use]
60 pub fn is_address_prefix(self) -> bool {
61 matches!(self, Self::AddressPrefix | Self::AddressPrefixLegacy)
62 }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
67pub enum OrfSendReceive {
68 Receive,
70 Send,
72 Both,
74 Unknown(u8),
76}
77
78impl OrfSendReceive {
79 #[must_use]
81 pub fn from_u8(value: u8) -> Self {
82 match value {
83 orf::SEND_RECEIVE_RECEIVE => Self::Receive,
84 orf::SEND_RECEIVE_SEND => Self::Send,
85 orf::SEND_RECEIVE_BOTH => Self::Both,
86 other => Self::Unknown(other),
87 }
88 }
89
90 #[must_use]
92 pub fn as_u8(self) -> u8 {
93 match self {
94 Self::Receive => orf::SEND_RECEIVE_RECEIVE,
95 Self::Send => orf::SEND_RECEIVE_SEND,
96 Self::Both => orf::SEND_RECEIVE_BOTH,
97 Self::Unknown(value) => value,
98 }
99 }
100
101 #[must_use]
103 pub fn can_send(self) -> bool {
104 matches!(self, Self::Send | Self::Both)
105 }
106
107 #[must_use]
109 pub fn can_receive(self) -> bool {
110 matches!(self, Self::Receive | Self::Both)
111 }
112}
113
114#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116pub struct OrfCapType {
117 pub orf_type: OrfType,
119 pub send_receive: OrfSendReceive,
121}
122
123#[derive(Debug, Clone, PartialEq, Eq)]
125pub struct OrfCapEntry {
126 pub afi: Afi,
128 pub safi: Safi,
130 pub orf_types: Vec<OrfCapType>,
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
136pub enum WhenToRefresh {
137 Immediate,
139 Defer,
141 Unknown(u8),
143}
144
145impl WhenToRefresh {
146 #[must_use]
148 pub fn from_u8(value: u8) -> Self {
149 match value {
150 orf::WHEN_IMMEDIATE => Self::Immediate,
151 orf::WHEN_DEFER => Self::Defer,
152 other => Self::Unknown(other),
153 }
154 }
155
156 #[must_use]
158 pub fn as_u8(self) -> u8 {
159 match self {
160 Self::Immediate => orf::WHEN_IMMEDIATE,
161 Self::Defer => orf::WHEN_DEFER,
162 Self::Unknown(value) => value,
163 }
164 }
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
169pub enum OrfAction {
170 Add,
172 Remove,
174 RemoveAll,
176}
177
178#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
180pub enum OrfMatch {
181 Permit,
183 Deny,
185}
186
187#[derive(Debug, Clone, Copy, PartialEq, Eq)]
192pub struct AddressPrefixOrf {
193 pub action: OrfAction,
195 pub match_: OrfMatch,
197 pub sequence: u32,
199 pub min_len: u8,
201 pub max_len: u8,
203 pub prefix: Option<Prefix>,
205}
206
207#[derive(Debug, Clone, PartialEq, Eq)]
209pub enum OrfEntries {
210 AddressPrefix(Vec<AddressPrefixOrf>),
212 Raw(Bytes),
215 Malformed(Bytes),
222}
223
224#[derive(Debug, Clone, PartialEq, Eq)]
226pub struct OrfEntryGroup {
227 pub orf_type: OrfType,
229 pub entries: OrfEntries,
231}
232
233#[derive(Debug, Clone, PartialEq, Eq)]
236pub struct OrfPayload {
237 pub when_to_refresh: WhenToRefresh,
239 pub groups: Vec<OrfEntryGroup>,
241}
242
243#[must_use]
247pub fn capability_value_len(entries: &[OrfCapEntry]) -> usize {
248 entries.iter().map(|e| 5 + 2 * e.orf_types.len()).sum()
250}
251
252pub fn encode_capability_value(entries: &[OrfCapEntry], buf: &mut impl BufMut) {
254 for entry in entries {
255 buf.put_u16(entry.afi as u16);
256 buf.put_u8(0); buf.put_u8(entry.safi as u8);
258 let count = u8::try_from(entry.orf_types.len()).unwrap_or(u8::MAX);
261 buf.put_u8(count);
262 for t in &entry.orf_types {
263 buf.put_u8(t.orf_type.as_u8());
264 buf.put_u8(t.send_receive.as_u8());
265 }
266 }
267}
268
269#[must_use]
273pub fn decode_capability_value(mut raw: &[u8]) -> Option<Vec<OrfCapEntry>> {
274 if raw.is_empty() {
277 return None;
278 }
279 let mut entries = Vec::new();
280 while !raw.is_empty() {
281 if raw.len() < 5 {
282 return None;
283 }
284 let afi_raw = u16::from_be_bytes([raw[0], raw[1]]);
285 let safi_raw = raw[3];
286 let count = usize::from(raw[4]);
287 raw = &raw[5..];
288 if raw.len() < count * 2 {
289 return None;
290 }
291 let afi = Afi::from_u16(afi_raw)?;
292 let safi = Safi::from_u8(safi_raw)?;
293 let mut orf_types = Vec::with_capacity(count);
294 for _ in 0..count {
295 orf_types.push(OrfCapType {
296 orf_type: OrfType::from_u8(raw[0]),
297 send_receive: OrfSendReceive::from_u8(raw[1]),
298 });
299 raw = &raw[2..];
300 }
301 entries.push(OrfCapEntry {
302 afi,
303 safi,
304 orf_types,
305 });
306 }
307 Some(entries)
308}
309
310pub fn decode_route_refresh_orf(
325 buf: &mut impl Buf,
326 family: Option<(Afi, Safi)>,
327) -> Result<OrfPayload, DecodeError> {
328 if buf.remaining() < 1 {
329 return Err(DecodeError::Incomplete {
330 needed: 1,
331 available: buf.remaining(),
332 });
333 }
334 let when_to_refresh = WhenToRefresh::from_u8(buf.get_u8());
335
336 let mut groups = Vec::new();
337 while buf.remaining() > 0 {
338 if buf.remaining() < 3 {
339 return Err(DecodeError::Incomplete {
340 needed: 3,
341 available: buf.remaining(),
342 });
343 }
344 let orf_type = OrfType::from_u8(buf.get_u8());
345 let len = usize::from(buf.get_u16());
346 if buf.remaining() < len {
347 return Err(DecodeError::Incomplete {
348 needed: len,
349 available: buf.remaining(),
350 });
351 }
352 let group_bytes = buf.copy_to_bytes(len);
353 let parse_family = match family {
354 Some((afi @ (Afi::Ipv4 | Afi::Ipv6), Safi::Unicast))
355 if orf_type.is_address_prefix() =>
356 {
357 Some(afi)
358 }
359 _ => None,
360 };
361 let entries = if let Some(afi) = parse_family {
362 match decode_address_prefix_entries(&group_bytes, afi) {
365 Ok(parsed) => OrfEntries::AddressPrefix(parsed),
366 Err(_) => OrfEntries::Malformed(group_bytes),
367 }
368 } else {
369 OrfEntries::Raw(group_bytes)
370 };
371 groups.push(OrfEntryGroup { orf_type, entries });
372 }
373
374 Ok(OrfPayload {
375 when_to_refresh,
376 groups,
377 })
378}
379
380pub fn encode_route_refresh_orf(
389 payload: &OrfPayload,
390 buf: &mut impl BufMut,
391) -> Result<(), crate::error::EncodeError> {
392 buf.put_u8(payload.when_to_refresh.as_u8());
393 for group in &payload.groups {
394 let mut group_buf = bytes::BytesMut::new();
395 match &group.entries {
396 OrfEntries::AddressPrefix(entries) => {
397 for entry in entries {
398 encode_address_prefix_entry(entry, &mut group_buf);
399 }
400 }
401 OrfEntries::Raw(raw) | OrfEntries::Malformed(raw) => group_buf.put_slice(raw),
402 }
403 let len = u16::try_from(group_buf.len()).map_err(|_| {
404 crate::error::EncodeError::ValueOutOfRange {
405 field: "orf_group_length",
406 value: group_buf.len().to_string(),
407 }
408 })?;
409 buf.put_u8(group.orf_type.as_u8());
410 buf.put_u16(len);
411 buf.put_slice(&group_buf);
412 }
413 Ok(())
414}
415
416#[must_use]
419pub fn route_refresh_orf_len(payload: &OrfPayload) -> usize {
420 let mut len = 1;
421 for group in &payload.groups {
422 let entry_bytes = match &group.entries {
423 OrfEntries::AddressPrefix(entries) => {
424 entries.iter().map(address_prefix_entry_len).sum::<usize>()
425 }
426 OrfEntries::Raw(raw) | OrfEntries::Malformed(raw) => raw.len(),
427 };
428 len += 3 + entry_bytes;
429 }
430 len
431}
432
433fn address_prefix_entry_len(entry: &AddressPrefixOrf) -> usize {
434 match entry.action {
435 OrfAction::RemoveAll => 1,
436 OrfAction::Add | OrfAction::Remove => {
437 let prefix_bytes = entry
439 .prefix
440 .map_or(0, |p| usize::from(p.prefix_len().div_ceil(8)));
441 8 + prefix_bytes
442 }
443 }
444}
445
446fn decode_address_prefix_entries(
447 mut raw: &[u8],
448 family: Afi,
449) -> Result<Vec<AddressPrefixOrf>, DecodeError> {
450 let mut entries = Vec::new();
451 while !raw.is_empty() {
452 let header = raw[0];
453 raw = &raw[1..];
454 let match_ = if header & orf::MATCH_MASK != 0 {
455 OrfMatch::Deny
456 } else {
457 OrfMatch::Permit
458 };
459 let action = match header & orf::ACTION_MASK {
460 orf::ACTION_ADD => OrfAction::Add,
461 orf::ACTION_REMOVE => OrfAction::Remove,
462 orf::ACTION_REMOVE_ALL => OrfAction::RemoveAll,
463 _ => {
465 return Err(DecodeError::InvalidNetworkField {
466 detail: format!("ORF entry has undefined Action in header {header:#x}"),
467 data: vec![header],
468 });
469 }
470 };
471 if action == OrfAction::RemoveAll {
472 entries.push(AddressPrefixOrf {
473 action,
474 match_,
475 sequence: 0,
476 min_len: 0,
477 max_len: 0,
478 prefix: None,
479 });
480 continue;
481 }
482
483 if raw.len() < 7 {
485 return Err(DecodeError::Incomplete {
486 needed: 7,
487 available: raw.len(),
488 });
489 }
490 let sequence = u32::from_be_bytes([raw[0], raw[1], raw[2], raw[3]]);
491 let min_len = raw[4];
492 let max_len = raw[5];
493 let prefix_len = raw[6];
494 raw = &raw[7..];
495
496 let prefix = decode_orf_prefix(&mut raw, family, prefix_len)?;
497 entries.push(AddressPrefixOrf {
498 action,
499 match_,
500 sequence,
501 min_len,
502 max_len,
503 prefix: Some(prefix),
504 });
505 }
506 Ok(entries)
507}
508
509fn decode_orf_prefix(raw: &mut &[u8], family: Afi, prefix_len: u8) -> Result<Prefix, DecodeError> {
510 let max_len = match family {
511 Afi::Ipv4 => 32,
512 Afi::Ipv6 => 128,
513 Afi::L2Vpn => unreachable!("Address-Prefix ORF parser is gated to IP unicast families"),
514 };
515 if prefix_len > max_len {
516 return Err(DecodeError::InvalidNetworkField {
517 detail: format!("ORF prefix length {prefix_len} exceeds {max_len}"),
518 data: vec![prefix_len],
519 });
520 }
521 let byte_count = usize::from(prefix_len.div_ceil(8));
522 if raw.len() < byte_count {
523 return Err(DecodeError::Incomplete {
524 needed: byte_count,
525 available: raw.len(),
526 });
527 }
528 let prefix = match family {
529 Afi::Ipv4 => {
530 let mut octets = [0u8; 4];
531 octets[..byte_count].copy_from_slice(&raw[..byte_count]);
532 Prefix::V4(Ipv4Prefix::new(Ipv4Addr::from(octets), prefix_len))
533 }
534 Afi::Ipv6 => {
535 let mut octets = [0u8; 16];
536 octets[..byte_count].copy_from_slice(&raw[..byte_count]);
537 Prefix::V6(Ipv6Prefix::new(Ipv6Addr::from(octets), prefix_len))
538 }
539 Afi::L2Vpn => unreachable!("Address-Prefix ORF parser is gated to IP unicast families"),
540 };
541 *raw = &raw[byte_count..];
542 Ok(prefix)
543}
544
545fn encode_address_prefix_entry(entry: &AddressPrefixOrf, buf: &mut impl BufMut) {
546 let action_bits = match entry.action {
547 OrfAction::Add => orf::ACTION_ADD,
548 OrfAction::Remove => orf::ACTION_REMOVE,
549 OrfAction::RemoveAll => orf::ACTION_REMOVE_ALL,
550 };
551 let match_bits = match entry.match_ {
552 OrfMatch::Permit => 0,
553 OrfMatch::Deny => orf::MATCH_DENY,
554 };
555 buf.put_u8(action_bits | match_bits);
556 if entry.action == OrfAction::RemoveAll {
557 return;
558 }
559 buf.put_u32(entry.sequence);
560 buf.put_u8(entry.min_len);
561 buf.put_u8(entry.max_len);
562 match entry.prefix {
563 Some(Prefix::V4(p)) => {
564 buf.put_u8(p.len);
565 let n = usize::from(p.len.div_ceil(8));
566 buf.put_slice(&p.addr.octets()[..n]);
567 }
568 Some(Prefix::V6(p)) => {
569 buf.put_u8(p.len);
570 let n = usize::from(p.len.div_ceil(8));
571 buf.put_slice(&p.addr.octets()[..n]);
572 }
573 None => buf.put_u8(0),
574 }
575}
576
577#[cfg(test)]
578mod tests {
579 use super::*;
580 use bytes::BytesMut;
581
582 fn ap(
583 action: OrfAction,
584 match_: OrfMatch,
585 sequence: u32,
586 min_len: u8,
587 max_len: u8,
588 prefix: Option<Prefix>,
589 ) -> AddressPrefixOrf {
590 AddressPrefixOrf {
591 action,
592 match_,
593 sequence,
594 min_len,
595 max_len,
596 prefix,
597 }
598 }
599
600 fn v4(addr: [u8; 4], len: u8) -> Prefix {
601 Prefix::V4(Ipv4Prefix::new(Ipv4Addr::from(addr), len))
602 }
603
604 #[test]
605 fn capability_value_roundtrip_receive() {
606 let entries = vec![
607 OrfCapEntry {
608 afi: Afi::Ipv4,
609 safi: Safi::Unicast,
610 orf_types: vec![OrfCapType {
611 orf_type: OrfType::AddressPrefix,
612 send_receive: OrfSendReceive::Receive,
613 }],
614 },
615 OrfCapEntry {
616 afi: Afi::Ipv6,
617 safi: Safi::Unicast,
618 orf_types: vec![
619 OrfCapType {
620 orf_type: OrfType::AddressPrefix,
621 send_receive: OrfSendReceive::Both,
622 },
623 OrfCapType {
624 orf_type: OrfType::AddressPrefixLegacy,
625 send_receive: OrfSendReceive::Send,
626 },
627 ],
628 },
629 ];
630 let mut buf = BytesMut::new();
631 encode_capability_value(&entries, &mut buf);
632 assert_eq!(buf.len(), capability_value_len(&entries));
633 let decoded = decode_capability_value(&buf).unwrap();
634 assert_eq!(decoded, entries);
635 }
636
637 #[test]
638 fn capability_value_unknown_type_preserved() {
639 let entries = vec![OrfCapEntry {
641 afi: Afi::Ipv4,
642 safi: Safi::Unicast,
643 orf_types: vec![OrfCapType {
644 orf_type: OrfType::Unknown(200),
645 send_receive: OrfSendReceive::Receive,
646 }],
647 }];
648 let mut buf = BytesMut::new();
649 encode_capability_value(&entries, &mut buf);
650 let decoded = decode_capability_value(&buf).unwrap();
651 assert_eq!(decoded, entries);
652 }
653
654 #[test]
655 fn capability_value_unknown_afi_rejected() {
656 let raw = [0u8, 99, 0, 1, 1, 64, 1];
658 assert!(decode_capability_value(&raw).is_none());
659 }
660
661 #[test]
662 fn capability_value_truncated_rejected() {
663 let raw = [0u8, 1, 0, 1]; assert!(decode_capability_value(&raw).is_none());
665 }
666
667 #[test]
668 fn rr_orf_roundtrip_add_permit_and_deny() {
669 let payload = OrfPayload {
670 when_to_refresh: WhenToRefresh::Immediate,
671 groups: vec![OrfEntryGroup {
672 orf_type: OrfType::AddressPrefix,
673 entries: OrfEntries::AddressPrefix(vec![
674 ap(
675 OrfAction::Add,
676 OrfMatch::Permit,
677 10,
678 24,
679 32,
680 Some(v4([10, 0, 0, 0], 8)),
681 ),
682 ap(
683 OrfAction::Add,
684 OrfMatch::Deny,
685 20,
686 0,
687 0,
688 Some(v4([192, 168, 0, 0], 16)),
689 ),
690 ]),
691 }],
692 };
693 let mut buf = BytesMut::new();
694 encode_route_refresh_orf(&payload, &mut buf).unwrap();
695 assert_eq!(buf.len(), route_refresh_orf_len(&payload));
696 let mut cursor = buf.freeze();
697 let decoded =
698 decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv4, Safi::Unicast))).unwrap();
699 assert_eq!(decoded, payload);
700 }
701
702 #[test]
703 fn rr_orf_roundtrip_remove_and_remove_all() {
704 let payload = OrfPayload {
705 when_to_refresh: WhenToRefresh::Defer,
706 groups: vec![OrfEntryGroup {
707 orf_type: OrfType::AddressPrefix,
708 entries: OrfEntries::AddressPrefix(vec![
709 ap(OrfAction::RemoveAll, OrfMatch::Permit, 0, 0, 0, None),
710 ap(
711 OrfAction::Remove,
712 OrfMatch::Permit,
713 5,
714 0,
715 0,
716 Some(v4([172, 16, 0, 0], 12)),
717 ),
718 ]),
719 }],
720 };
721 let mut buf = BytesMut::new();
722 encode_route_refresh_orf(&payload, &mut buf).unwrap();
723 let mut cursor = buf.freeze();
724 let decoded =
725 decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv4, Safi::Unicast))).unwrap();
726 assert_eq!(decoded, payload);
727 }
728
729 #[test]
730 fn rr_orf_roundtrip_default_route_and_host_route() {
731 let payload = OrfPayload {
732 when_to_refresh: WhenToRefresh::Immediate,
733 groups: vec![OrfEntryGroup {
734 orf_type: OrfType::AddressPrefix,
735 entries: OrfEntries::AddressPrefix(vec![
736 ap(
737 OrfAction::Add,
738 OrfMatch::Permit,
739 1,
740 0,
741 0,
742 Some(v4([0, 0, 0, 0], 0)),
743 ),
744 ap(
745 OrfAction::Add,
746 OrfMatch::Permit,
747 2,
748 0,
749 0,
750 Some(v4([10, 1, 2, 3], 32)),
751 ),
752 ]),
753 }],
754 };
755 let mut buf = BytesMut::new();
756 encode_route_refresh_orf(&payload, &mut buf).unwrap();
757 let mut cursor = buf.freeze();
758 let decoded =
759 decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv4, Safi::Unicast))).unwrap();
760 assert_eq!(decoded, payload);
761 }
762
763 #[test]
764 fn rr_orf_roundtrip_ipv6_host_route() {
765 let p = Prefix::V6(Ipv6Prefix::new("2001:db8::1".parse().unwrap(), 128));
766 let payload = OrfPayload {
767 when_to_refresh: WhenToRefresh::Immediate,
768 groups: vec![OrfEntryGroup {
769 orf_type: OrfType::AddressPrefix,
770 entries: OrfEntries::AddressPrefix(vec![ap(
771 OrfAction::Add,
772 OrfMatch::Deny,
773 7,
774 64,
775 128,
776 Some(p),
777 )]),
778 }],
779 };
780 let mut buf = BytesMut::new();
781 encode_route_refresh_orf(&payload, &mut buf).unwrap();
782 let mut cursor = buf.freeze();
783 let decoded =
784 decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv6, Safi::Unicast))).unwrap();
785 assert_eq!(decoded, payload);
786 }
787
788 #[test]
789 fn rr_orf_legacy_type_128_parsed() {
790 let payload = OrfPayload {
791 when_to_refresh: WhenToRefresh::Immediate,
792 groups: vec![OrfEntryGroup {
793 orf_type: OrfType::AddressPrefixLegacy,
794 entries: OrfEntries::AddressPrefix(vec![ap(
795 OrfAction::Add,
796 OrfMatch::Permit,
797 1,
798 0,
799 0,
800 Some(v4([10, 0, 0, 0], 8)),
801 )]),
802 }],
803 };
804 let mut buf = BytesMut::new();
805 encode_route_refresh_orf(&payload, &mut buf).unwrap();
806 let mut cursor = buf.freeze();
807 let decoded =
808 decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv4, Safi::Unicast))).unwrap();
809 assert_eq!(decoded, payload);
810 }
811
812 #[test]
813 fn rr_orf_unknown_type_preserved_as_raw() {
814 let mut buf = BytesMut::new();
816 buf.put_u8(WhenToRefresh::Immediate.as_u8());
817 buf.put_u8(9); buf.put_u16(3);
819 buf.put_slice(&[0xAA, 0xBB, 0xCC]);
820 let mut cursor = buf.freeze();
821 let decoded =
822 decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv4, Safi::Unicast))).unwrap();
823 assert_eq!(decoded.groups.len(), 1);
824 assert_eq!(decoded.groups[0].orf_type, OrfType::Unknown(9));
825 assert_eq!(
826 decoded.groups[0].entries,
827 OrfEntries::Raw(Bytes::from_static(&[0xAA, 0xBB, 0xCC]))
828 );
829 }
830
831 #[test]
832 fn rr_orf_address_prefix_without_family_preserved_as_raw() {
833 let mut buf = BytesMut::new();
834 buf.put_u8(WhenToRefresh::Immediate.as_u8());
835 buf.put_u8(OrfType::AddressPrefix.as_u8());
836 buf.put_u16(8);
837 buf.put_u8(orf::ACTION_ADD);
838 buf.put_u32(1);
839 buf.put_u8(0);
840 buf.put_u8(0);
841 buf.put_u8(40); let mut cursor = buf.freeze();
843 let decoded = decode_route_refresh_orf(&mut cursor, None).unwrap();
844 assert_eq!(
845 decoded.groups[0].entries,
846 OrfEntries::Raw(Bytes::from_static(&[orf::ACTION_ADD, 0, 0, 0, 1, 0, 0, 40]))
847 );
848 }
849
850 #[test]
851 fn rr_orf_address_prefix_non_ip_family_preserved_as_raw() {
852 let mut buf = BytesMut::new();
853 buf.put_u8(WhenToRefresh::Immediate.as_u8());
854 buf.put_u8(OrfType::AddressPrefix.as_u8());
855 buf.put_u16(8);
856 buf.put_u8(orf::ACTION_ADD);
857 buf.put_u32(1);
858 buf.put_u8(0);
859 buf.put_u8(0);
860 buf.put_u8(40);
861 let mut cursor = buf.freeze();
862 let decoded =
863 decode_route_refresh_orf(&mut cursor, Some((Afi::L2Vpn, Safi::Evpn))).unwrap();
864 assert_eq!(
865 decoded.groups[0].entries,
866 OrfEntries::Raw(Bytes::from_static(&[orf::ACTION_ADD, 0, 0, 0, 1, 0, 0, 40]))
867 );
868 }
869
870 #[test]
871 fn rr_orf_address_prefix_non_unicast_family_preserved_as_raw() {
872 let mut buf = BytesMut::new();
873 buf.put_u8(WhenToRefresh::Immediate.as_u8());
874 buf.put_u8(OrfType::AddressPrefix.as_u8());
875 buf.put_u16(8);
876 buf.put_u8(orf::ACTION_ADD);
877 buf.put_u32(1);
878 buf.put_u8(0);
879 buf.put_u8(0);
880 buf.put_u8(40);
881 let mut cursor = buf.freeze();
882 let decoded =
883 decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv4, Safi::FlowSpec))).unwrap();
884 assert_eq!(
885 decoded.groups[0].entries,
886 OrfEntries::Raw(Bytes::from_static(&[orf::ACTION_ADD, 0, 0, 0, 1, 0, 0, 40]))
887 );
888 }
889
890 #[test]
891 fn rr_orf_prefix_len_over_family_max_is_malformed_not_error() {
892 let mut buf = BytesMut::new();
895 buf.put_u8(WhenToRefresh::Immediate.as_u8());
896 buf.put_u8(OrfType::AddressPrefix.as_u8());
897 buf.put_u16(8);
898 buf.put_u8(orf::ACTION_ADD);
899 buf.put_u32(1);
900 buf.put_u8(0);
901 buf.put_u8(0);
902 buf.put_u8(40); let mut cursor = buf.freeze();
904 let decoded =
905 decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv4, Safi::Unicast))).unwrap();
906 assert!(matches!(
907 decoded.groups[0].entries,
908 OrfEntries::Malformed(_)
909 ));
910 }
911
912 #[test]
913 fn rr_orf_undefined_action_is_malformed_not_error() {
914 let mut buf = BytesMut::new();
915 buf.put_u8(WhenToRefresh::Immediate.as_u8());
916 buf.put_u8(OrfType::AddressPrefix.as_u8());
917 buf.put_u16(1);
918 buf.put_u8(0x40); let mut cursor = buf.freeze();
920 let decoded =
921 decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv4, Safi::Unicast))).unwrap();
922 assert!(matches!(
923 decoded.groups[0].entries,
924 OrfEntries::Malformed(_)
925 ));
926 }
927
928 #[test]
929 fn rr_orf_truncated_group_rejected() {
930 let mut buf = BytesMut::new();
931 buf.put_u8(WhenToRefresh::Immediate.as_u8());
932 buf.put_u8(OrfType::AddressPrefix.as_u8());
933 buf.put_u16(20); let mut cursor = buf.freeze();
935 assert!(decode_route_refresh_orf(&mut cursor, Some((Afi::Ipv4, Safi::Unicast))).is_err());
936 }
937}