Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Trying to implement bgp-actions.set_next_hop #250

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion daemon/src/config/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,32 @@ impl TryFrom<&Statement> for api::Statement {
med: None,
as_prepend: None,
ext_community: None,
nexthop: None,
nexthop: match a.bgp_actions.as_ref() {
Some(a) => {
if let Some(s) = a.set_next_hop.as_ref() {
match s.as_str() {
"self" => Some(api::NexthopAction {
self_: true,
unchanged: false,
address: String::new(),
}),
"unchanged" => Some(api::NexthopAction {
self_: false,
unchanged: true,
address: String::new(),
}),
_ => Some(api::NexthopAction {
self_: false,
unchanged: false,
address: s.to_string(),
}),
}
} else {
None
}
}
None => None,
},
local_pref: None,
large_community: None,
});
Expand Down
73 changes: 26 additions & 47 deletions daemon/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ impl GrpcService {
if attr.is_empty() {
None
} else {
Some(Arc::new(attr))
Some(attr)
}
},
),
Expand Down Expand Up @@ -952,7 +952,7 @@ impl GobgpApi for GrpcService {
request: tonic::Request<api::EnablePeerRequest>,
) -> Result<tonic::Response<()>, tonic::Status> {
if let Ok(peer_addr) = IpAddr::from_str(&request.into_inner().address) {
for (addr, mut p) in &mut GLOBAL.write().await.peers {
for (addr, p) in &mut GLOBAL.write().await.peers {
if addr == &peer_addr {
if p.admin_down {
p.admin_down = false;
Expand Down Expand Up @@ -981,7 +981,7 @@ impl GobgpApi for GrpcService {
request: tonic::Request<api::DisablePeerRequest>,
) -> Result<tonic::Response<()>, tonic::Status> {
if let Ok(peer_addr) = IpAddr::from_str(&request.into_inner().address) {
for (addr, mut p) in &mut GLOBAL.write().await.peers {
for (addr, p) in &mut GLOBAL.write().await.peers {
if addr == &peer_addr {
if p.admin_down {
return Err(tonic::Status::new(
Expand Down Expand Up @@ -2413,7 +2413,7 @@ impl RpkiClient {
.await
{
let (tx, rx) = mpsc::unbounded_channel();
let state = if let Some(mut client) =
let state = if let Some(client) =
GLOBAL.write().await.rpki_clients.get_mut(&sockaddr)
{
client.mgmt_tx = Some(tx);
Expand All @@ -2425,7 +2425,7 @@ impl RpkiClient {
} else {
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
}
if let Some(mut client) = GLOBAL.write().await.rpki_clients.get_mut(&sockaddr) {
if let Some(client) = GLOBAL.write().await.rpki_clients.get_mut(&sockaddr) {
if client.configured_time != configured_time {
break;
}
Expand Down Expand Up @@ -2977,7 +2977,7 @@ enum TableEvent {
Arc<table::Source>,
Family,
Vec<(packet::Net, u32)>,
Option<Arc<Vec<packet::Attribute>>>,
Option<Vec<packet::Attribute>>,
),
Disconnected(Arc<table::Source>),
// RPKI events
Expand Down Expand Up @@ -3011,7 +3011,7 @@ impl Table {
if let Some(Some(msg)) = futures.next().await {
match msg {
TableEvent::PassUpdate(source, family, nets, attrs) => match attrs {
Some(attrs) => {
Some(mut attrs) => {
let mut t = TABLE[idx].lock().await;
for bmp_tx in t.bmp_event_tx.values() {
let addpath = if let Some(e) = t.addpath.get(&source.remote_addr) {
Expand Down Expand Up @@ -3063,7 +3063,7 @@ impl Table {
for net in nets {
let mut filtered = false;
if let Some(a) = t.global_import_policy.as_ref() {
if t.rtable.apply_policy(a, &source, &net.0, &attrs)
if t.rtable.apply_policy(a, &source, &net.0, &mut attrs)
== table::Disposition::Reject
{
filtered = true;
Expand All @@ -3078,7 +3078,7 @@ impl Table {
filtered,
) {
if let Some(a) = t.global_export_policy.as_ref() {
if t.rtable.apply_policy(a, &source, &net.0, &attrs)
if t.rtable.apply_policy(a, &source, &net.0, &mut attrs)
== table::Disposition::Reject
{
continue;
Expand Down Expand Up @@ -3108,7 +3108,7 @@ impl Table {
),
update: packet::bgp::Message::Update {
reach: None,
attr: Arc::new(Vec::new()),
attr: Vec::new(),
unreach: Some((family, nets.to_owned())),
},
addpath,
Expand All @@ -3131,7 +3131,7 @@ impl Table {
),
body: bgp::Message::Update {
reach: None,
attr: Arc::new(Vec::new()),
attr: Vec::new(),
unreach: Some((family, nets.to_owned())),
},
addpath,
Expand All @@ -3148,7 +3148,7 @@ impl Table {
a,
&source,
&net.0,
&Arc::new(Vec::new()),
&mut Vec::new(),
) == table::Disposition::Reject
{
continue;
Expand Down Expand Up @@ -3320,7 +3320,7 @@ impl Handler {
&mut self,
reach: Option<(Family, Vec<(packet::Net, u32)>)>,
unreach: Option<(Family, Vec<(packet::Net, u32)>)>,
attr: Arc<Vec<packet::Attribute>>,
attr: Vec<packet::Attribute>,
) {
if let Some((family, reach)) = reach {
for net in reach {
Expand Down Expand Up @@ -3469,9 +3469,9 @@ impl Handler {
for i in 0..*NUM_TABLES {
let mut t = TABLE[i].lock().await;
for f in codec.channel.keys() {
for c in t.rtable.best(f).into_iter() {
for mut c in t.rtable.best(f).into_iter() {
if let Some(a) = t.global_export_policy.as_ref() {
if t.rtable.apply_policy(a, &c.source, &c.net, &c.attr)
if t.rtable.apply_policy(a, &c.source, &c.net, &mut c.attr)
== table::Disposition::Reject
{
continue;
Expand Down Expand Up @@ -3717,7 +3717,7 @@ impl Handler {
txbuf = bytes::BytesMut::with_capacity(txbuf_size);
let msg = bgp::Message::Update{
reach: None,
attr: Arc::new(Vec::new()),
attr: Vec::new(),
unreach: Some((*family, unreach)),
};
let _ = codec.encode(&msg, &mut txbuf);
Expand Down Expand Up @@ -3832,9 +3832,9 @@ impl Handler {

#[derive(Default)]
struct PendingTx {
reach: FnvHashMap<packet::Net, Arc<Vec<packet::Attribute>>>,
reach: FnvHashMap<packet::Net, Vec<packet::Attribute>>,
unreach: FnvHashSet<packet::Net>,
bucket: FnvHashMap<Arc<Vec<packet::Attribute>>, FnvHashSet<packet::Net>>,
bucket: FnvHashMap<Vec<packet::Attribute>, FnvHashSet<packet::Net>>,
sync: bool,
}

Expand Down Expand Up @@ -3933,60 +3933,39 @@ fn bucket() {
source: src.clone(),
family,
net: net1,
attr: Arc::new(attr1.clone()),
attr: attr1.clone(),
});

pending.insert_change(table::Change {
source: src.clone(),
family: Family::IPV4,
net: net2,
attr: Arc::new(vec![packet::Attribute::new_with_value(
packet::Attribute::ORIGIN,
0,
)
.unwrap()]),
attr: vec![packet::Attribute::new_with_value(packet::Attribute::ORIGIN, 0).unwrap()],
});

// a-1) and a-2) properly marged?
assert_eq!(1, pending.bucket.len());
assert_eq!(
2,
pending.bucket.get(&Arc::new(attr1.clone())).unwrap().len()
);
assert_eq!(2, pending.bucket.get(&attr1.clone()).unwrap().len());

// b-1)
pending.insert_change(table::Change {
source: src.clone(),
family,
net: net2,
attr: Arc::new(vec![packet::Attribute::new_with_value(
packet::Attribute::ORIGIN,
0,
)
.unwrap()]),
attr: vec![packet::Attribute::new_with_value(packet::Attribute::ORIGIN, 0).unwrap()],
});
assert_eq!(1, pending.bucket.len());
assert_eq!(
2,
pending.bucket.get(&Arc::new(attr1.clone())).unwrap().len()
);
assert_eq!(2, pending.bucket.get(&attr1.clone()).unwrap().len());

// b-2-2)
let attr2 = vec![packet::Attribute::new_with_value(packet::Attribute::ORIGIN, 1).unwrap()];
pending.insert_change(table::Change {
source: src.clone(),
family,
net: net2,
attr: Arc::new(vec![packet::Attribute::new_with_value(
packet::Attribute::ORIGIN,
1,
)
.unwrap()]),
attr: vec![packet::Attribute::new_with_value(packet::Attribute::ORIGIN, 1).unwrap()],
});
assert_eq!(2, pending.bucket.len());
assert_eq!(&Arc::new(attr2), pending.reach.get(&net2).unwrap());
assert_eq!(
1,
pending.bucket.get(&Arc::new(attr1.clone())).unwrap().len()
);
assert_eq!(&attr2, pending.reach.get(&net2).unwrap());
assert_eq!(1, pending.bucket.get(&attr1.clone()).unwrap().len());
}
27 changes: 13 additions & 14 deletions daemon/src/packet/bgp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use std::convert::{Into, TryFrom};
use std::io::Cursor;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
use std::sync::Arc;
use std::{fmt, io};
use tokio_util::codec::{Decoder, Encoder};

Expand Down Expand Up @@ -1475,7 +1474,7 @@ pub(crate) enum Message {
Update {
reach: Option<(Family, Vec<(Net, u32)>)>,
unreach: Option<(Family, Vec<(Net, u32)>)>,
attr: Arc<Vec<Attribute>>,
attr: Vec<Attribute>,
},
Notification {
code: u8,
Expand Down Expand Up @@ -1504,13 +1503,13 @@ impl Message {
if family == Family::IPV4 {
Message::Update {
reach: Some((Family::IPV4, Vec::new())),
attr: Arc::new(Vec::new()),
attr: Vec::new(),
unreach: None,
}
} else {
Message::Update {
reach: None,
attr: Arc::new(Vec::new()),
attr: Vec::new(),
unreach: Some((family, Vec::new())),
}
}
Expand Down Expand Up @@ -1685,7 +1684,7 @@ impl Codec {
fn mp_reach_encode(
&self,
buf_head: usize,
attrs: Arc<Vec<Attribute>>,
attrs: Vec<Attribute>,
dst: &mut BytesMut,
reach: &(Family, Vec<(Net, u32)>),
reach_idx: &mut usize,
Expand Down Expand Up @@ -1753,7 +1752,7 @@ impl Codec {
fn mp_unreach_encode(
&self,
buf_head: usize,
_: Arc<Vec<Attribute>>,
_: Vec<Attribute>,
dst: &mut BytesMut,
unreach: &(Family, Vec<(Net, u32)>),
unreach_idx: &mut usize,
Expand Down Expand Up @@ -2263,7 +2262,7 @@ impl Decoder for Codec {
return Ok(Some(Message::Update {
reach: Some((Family::IPV4, Vec::new())),
unreach: None,
attr: Arc::new(Vec::new()),
attr: Vec::new(),
}));
}

Expand Down Expand Up @@ -2424,7 +2423,7 @@ impl Decoder for Codec {
} else {
Some((reach_family, reach))
},
attr: Arc::new(attr),
attr: attr,
unreach: if unreach.is_empty() {
None
} else {
Expand Down Expand Up @@ -2552,11 +2551,11 @@ fn build_many_v4_route() {
let reach: Vec<(Net, u32)> = net.iter().cloned().map(|n| (n, 0)).collect();
let mut msg = Message::Update {
reach: Some((Family::IPV4, reach)),
attr: Arc::new(vec![
attr: vec![
Attribute::new_with_value(Attribute::ORIGIN, 0).unwrap(),
Attribute::new_with_bin(Attribute::AS_PATH, vec![2, 1, 1, 0, 0, 0]).unwrap(),
Attribute::new_with_bin(Attribute::NEXTHOP, vec![0, 0, 0, 0]).unwrap(),
]),
],
unreach: None,
};
let mut set = fnv::FnvHashSet::default();
Expand Down Expand Up @@ -2596,7 +2595,7 @@ fn build_many_v4_route() {
let unreach = net.iter().cloned().map(|n| (n, 0)).collect();
msg = Message::Update {
reach: None,
attr: Arc::new(Vec::new()),
attr: Vec::new(),
unreach: Some((Family::IPV4, unreach)),
};

Expand Down Expand Up @@ -2647,11 +2646,11 @@ fn many_mp_reach() {

let msg = Message::Update {
reach: Some((Family::IPV6, reach)),
attr: Arc::new(vec![
attr: vec![
Attribute::new_with_value(Attribute::ORIGIN, 0).unwrap(),
Attribute::new_with_bin(Attribute::AS_PATH, vec![2, 1, 1, 0, 0, 0]).unwrap(),
Attribute::new_with_bin(Attribute::NEXTHOP, (0..31).collect::<Vec<u8>>()).unwrap(),
]),
],
unreach: None,
};

Expand Down Expand Up @@ -2701,7 +2700,7 @@ fn many_mp_unreach() {

let msg = Message::Update {
reach: None,
attr: Arc::new(Vec::new()),
attr: Vec::new(),
unreach: Some((Family::IPV6, unreach)),
};

Expand Down
Loading