Skip to content

Commit 76d2e44

Browse files
committed
bgp: add otc attribute
Introduce the Only To Customer (OTC) optional transitive attribute. Signed-off-by: Paul Wekesa <paul1tw1@gmail.com>
1 parent b13dd94 commit 76d2e44

1 file changed

Lines changed: 45 additions & 3 deletions

File tree

holo-bgp/src/packet/attribute.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub struct BaseAttrs {
5858
pub atomic_aggregate: Option<()>,
5959
pub originator_id: Option<Ipv4Addr>,
6060
pub cluster_list: Option<ClusterList>,
61+
pub otc: Option<u32>,
6162
}
6263

6364
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
@@ -181,6 +182,11 @@ impl Attrs {
181182
atomic_aggregate::encode(buf);
182183
}
183184

185+
// Only To Customer (OTC) attribute.
186+
if let Some(otc) = self.base.otc {
187+
otc::encode(otc, buf);
188+
}
189+
184190
// AGGREGATOR attribute.
185191
if let Some(aggregator) = &self.base.aggregator {
186192
aggregator.encode(
@@ -278,6 +284,7 @@ impl Attrs {
278284
let mut ext_comm = None;
279285
let mut extv6_comm = None;
280286
let mut large_comm = None;
287+
let mut otc = None;
281288
let mut unknown = vec![];
282289
let mut withdraw = false;
283290

@@ -452,6 +459,7 @@ impl Attrs {
452459
AttrType::LargeCommunity => {
453460
LargeComms::decode(&mut buf, &mut large_comm)
454461
}
462+
AttrType::Otc => otc::decode(&mut buf, &mut otc),
455463
} {
456464
// Log malformed attribute.
457465
Debug::NbrAttrError(attr_type, error).log();
@@ -493,6 +501,7 @@ impl Attrs {
493501
atomic_aggregate,
494502
originator_id,
495503
cluster_list,
504+
otc,
496505
},
497506
comm,
498507
ext_comm,
@@ -549,6 +558,9 @@ impl Attrs {
549558
if let Some(large_comm) = &self.large_comm {
550559
length += large_comm.length();
551560
}
561+
if self.base.otc.is_some() {
562+
length += otc::length();
563+
}
552564

553565
length
554566
}
@@ -865,6 +877,37 @@ mod med {
865877
}
866878
}
867879

880+
// ==== Only To Customer(OTC) attribute ====
881+
882+
mod otc {
883+
use super::*;
884+
const LEN: u8 = 4;
885+
886+
pub(super) fn encode(otc: u32, buf: &mut BytesMut) {
887+
buf.put_u8(AttrFlags::OPTIONAL.bits());
888+
buf.put_u8(AttrType::Otc as u8);
889+
buf.put_u8(LEN);
890+
buf.put_u32(otc);
891+
}
892+
893+
pub(super) fn decode(
894+
buf: &mut Bytes,
895+
otc: &mut Option<u32>,
896+
) -> Result<(), AttrError> {
897+
if buf.remaining() != LEN as usize {
898+
return Err(AttrError::Withdraw);
899+
}
900+
901+
let value = buf.try_get_u32()?;
902+
*otc = Some(value);
903+
Ok(())
904+
}
905+
906+
pub(super) fn length() -> u16 {
907+
ATTR_MIN_LEN + LEN as u16
908+
}
909+
}
910+
868911
// ===== LOCAL_PREF attribute =====
869912

870913
mod local_pref {
@@ -1450,9 +1493,8 @@ fn attribute_flags(attr_type: AttrType) -> AttrFlags {
14501493
| AttrType::As4Path
14511494
| AttrType::As4Aggregator
14521495
| AttrType::Extv6Community
1453-
| AttrType::LargeCommunity => {
1454-
AttrFlags::TRANSITIVE | AttrFlags::OPTIONAL
1455-
}
1496+
| AttrType::LargeCommunity
1497+
| AttrType::Otc => AttrFlags::TRANSITIVE | AttrFlags::OPTIONAL,
14561498
}
14571499
}
14581500

0 commit comments

Comments
 (0)