diff --git a/route/bgp.go b/route/bgp.go index 47f7db4fc15980936e174ffa540fd3c09bb04a7e..cde74bddecd79c022dc1f204ffb6a26b6879e2be 100644 --- a/route/bgp.go +++ b/route/bgp.go @@ -154,6 +154,14 @@ func (b *BGPPath) Print() string { return ret } +func (b *BGPPath) Prepend(asn uint32, times uint16) { + for i := 0; uint16(i) < times; i++ { + b.ASPath = fmt.Sprintf("%d %s", asn, b.ASPath) + } + + b.ASPathLen = b.ASPathLen + uint16(times) +} + func uint32To4Byte(addr uint32) [4]byte { slice := convert.Uint32Byte(addr) ret := [4]byte{ @@ -164,3 +172,12 @@ func uint32To4Byte(addr uint32) [4]byte { } return ret } + +func (p *BGPPath) Copy() *BGPPath { + if p == nil { + return nil + } + + cp := *p + return &cp +} diff --git a/route/path.go b/route/path.go index 544b83b485c106870b8ff7a251539187c85a06d6..ef2e881798212232fc6e116d2df2764e7d6207d3 100644 --- a/route/path.go +++ b/route/path.go @@ -100,3 +100,15 @@ func (p *Path) Print() string { return ret } + +func (p *Path) Copy() *Path { + if p == nil { + return nil + } + + cp := *p + cp.BGPPath = cp.BGPPath.Copy() + cp.StaticPath = cp.StaticPath.Copy() + + return &cp +} diff --git a/route/static.go b/route/static.go index 483138f04874ff7f50185ba3fcfb04fb007c6029..0ab6b26e3dc01c58b756efca28935b2e8e4e9d5a 100644 --- a/route/static.go +++ b/route/static.go @@ -23,3 +23,12 @@ func (s *StaticPath) Compare(t *StaticPath) int8 { func (s *StaticPath) ECMP(t *StaticPath) bool { return true } + +func (s *StaticPath) Copy() *StaticPath { + if s == nil { + return nil + } + + cp := *s + return &cp +} diff --git a/routingtable/filter/actions/as_path_prepend_action.go b/routingtable/filter/actions/as_path_prepend_action.go new file mode 100644 index 0000000000000000000000000000000000000000..30d63ca783fd91a9530f336f3311106c57ac5968 --- /dev/null +++ b/routingtable/filter/actions/as_path_prepend_action.go @@ -0,0 +1,29 @@ +package actions + +import ( + "github.com/bio-routing/bio-rd/net" + "github.com/bio-routing/bio-rd/route" +) + +type ASPathPrependAction struct { + asn uint32 + times uint16 +} + +func NewASPathPrependAction(asn uint32, times uint16) *ASPathPrependAction { + return &ASPathPrependAction{ + asn: asn, + times: times, + } +} + +func (a *ASPathPrependAction) Do(p net.Prefix, pa *route.Path) (modPath *route.Path, reject bool) { + if pa.BGPPath == nil { + return pa, false + } + + modified := pa.Copy() + modified.BGPPath.Prepend(a.asn, a.times) + + return modified, false +} diff --git a/routingtable/filter/actions/filter_action.go b/routingtable/filter/actions/filter_action.go new file mode 100644 index 0000000000000000000000000000000000000000..7a2665146922719766b880f9093eb1049c6ae018 --- /dev/null +++ b/routingtable/filter/actions/filter_action.go @@ -0,0 +1,10 @@ +package actions + +import ( + "github.com/bio-routing/bio-rd/net" + "github.com/bio-routing/bio-rd/route" +) + +type FilterAction interface { + Do(p net.Prefix, pa *route.Path) (modPath *route.Path, reject bool) +} diff --git a/routingtable/filter/actions/set_local_pref_action.go b/routingtable/filter/actions/set_local_pref_action.go index 1b59be48e16b844aae069c5795d7acc691e87612..e60b6faa0ab5e4e986f785d7b8322db2c6492e34 100644 --- a/routingtable/filter/actions/set_local_pref_action.go +++ b/routingtable/filter/actions/set_local_pref_action.go @@ -3,20 +3,19 @@ package actions import ( "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/route" - "github.com/bio-routing/bio-rd/routingtable/filter" ) -type setLocalPrefAction struct { +type SetLocalPrefAction struct { pref uint32 } -func NewSetLocalPrefAction(pref uint32) filter.FilterAction { - return &setLocalPrefAction{ +func NewSetLocalPrefAction(pref uint32) *SetLocalPrefAction { + return &SetLocalPrefAction{ pref: pref, } } -func (a *setLocalPrefAction) Do(p net.Prefix, pa *route.Path) (modPath *route.Path, reject bool) { +func (a *SetLocalPrefAction) Do(p net.Prefix, pa *route.Path) (modPath *route.Path, reject bool) { if pa.BGPPath == nil { return pa, false } diff --git a/routingtable/filter/actions/set_nexthop_action.go b/routingtable/filter/actions/set_nexthop_action.go index 41200a845a6f4ba6c31f9e30e202971eca1be9cb..f178f61802882157856fc1f4bf15c8d9f0b08dc6 100644 --- a/routingtable/filter/actions/set_nexthop_action.go +++ b/routingtable/filter/actions/set_nexthop_action.go @@ -3,26 +3,25 @@ package actions import ( "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/route" - "github.com/bio-routing/bio-rd/routingtable/filter" ) -type setNextHopAction struct { +type SetNextHopAction struct { addr uint32 } -func NewSetNextHopAction(addr uint32) filter.FilterAction { - return &setNextHopAction{ +func NewSetNextHopAction(addr uint32) *SetNextHopAction { + return &SetNextHopAction{ addr: addr, } } -func (a *setNextHopAction) Do(p net.Prefix, pa *route.Path) (modPath *route.Path, reject bool) { +func (a *SetNextHopAction) Do(p net.Prefix, pa *route.Path) (modPath *route.Path, reject bool) { if pa.BGPPath == nil { return pa, false } - modified := *pa + modified := pa.Copy() modified.BGPPath.NextHop = a.addr - return &modified, false + return modified, false }