diff --git a/protocols/fib/fib.go b/protocols/fib/fib.go index 5b3b7beddc6739f4a309d60de28e5c7040cbcfdd..2e84e42a9f127f72a825eaa986f7a1076ee55731 100644 --- a/protocols/fib/fib.go +++ b/protocols/fib/fib.go @@ -15,6 +15,9 @@ import ( type fibOsAdapter interface { addPath(pfx bnet.Prefix, paths []*route.FIBPath) error removePath(pfx bnet.Prefix, path *route.FIBPath) error + getFibName() string + needsVrfID() bool + setVrfID(vrdID string) error } // FIB is forwarding information base @@ -43,6 +46,22 @@ func New(v *vrf.VRF) (*FIB, error) { return n, nil } +// SetVrfID specifies the vrf id for the fib implementation. +// Some fib implementations don't need a VRF-ID. +// This method will return an error, in case the hardware specific fib implementation +// doesn't support or need a vrfId +func (f *FIB) SetVrfID(vrfID string) error { + if f.osAdapter != nil { + return fmt.Errorf("osAdapter is nil") + } + + if !f.osAdapter.needsVrfID() { + return fmt.Errorf("The fib implementation for %s doesn't need a routing table identifier", f.osAdapter.getFibName()) + } + + return f.osAdapter.setVrfID(vrfID) +} + // Start the Netlink module func (f *FIB) Start() error { if f.osAdapter == nil { @@ -57,15 +76,16 @@ func (f *FIB) Start() error { } // register to all ribs in VRF - vrfRIBs := f.vrf.GetRIBNames() - for _, ribName := range vrfRIBs { - rib, found := f.vrf.RIBByName(ribName) - if !found { - continue - } + rib4, found := f.vrf.RIBByName("inet.0") + if found { + // from locRib to FIB + rib4.RegisterWithOptions(f, options) + } + rib6, found := f.vrf.RIBByName("inet6.0") + if found { // from locRib to FIB - rib.RegisterWithOptions(f, options) + rib6.RegisterWithOptions(f, options) } return nil diff --git a/protocols/fib/fib_adapter_darwin.go b/protocols/fib/fib_adapter_darwin.go index 50c4991fe7999cbafcc2db3a1d38afb414a5337c..a77a98382c61090d4c44364d213d8bb271186648 100644 --- a/protocols/fib/fib_adapter_darwin.go +++ b/protocols/fib/fib_adapter_darwin.go @@ -15,6 +15,10 @@ type osFibAdapterDarwin struct { fib *FIB } +func (fib *osFibAdapterLinux) getFibName() string { + return "darwin" +} + func newOSFIBDarwin(f *FIB) (*osFibAdapterDarwin, error) { fib := &osFibAdapterDarwin{ fib: f, @@ -30,3 +34,11 @@ func (fib *osFibAdapterDarwin) addPath(pfx bnet.Prefix, paths []*route.FIBPath) func (fib *osFibAdapterDarwin) removePath(pfx bnet.Prefix, path *route.FIBPath) error { return fmt.Errorf("Not implemented") } + +func (fib *osFibAdapterDarwin) needsVrfID() bool { + return false +} + +func (fib *osFibAdapterDarwin) setVrfID(vrdID string) error { + return fmt.Errorf("Not implemented") +} diff --git a/protocols/fib/fib_adapter_linux.go b/protocols/fib/fib_adapter_linux.go index afad7734ffc1d905e698e09673dd5f70d4eafa87..5e0a2a686bf65322e0d3e7654f407d24bdf7262f 100644 --- a/protocols/fib/fib_adapter_linux.go +++ b/protocols/fib/fib_adapter_linux.go @@ -15,7 +15,24 @@ func (f *FIB) loadOSAdapter() { } type osFibAdapterLinux struct { - fib *FIB + fib *FIB + vrfID uint64 +} + +func (fib *osFibAdapterLinux) getFibName() string { + return "rt_netlink" +} + +func (fib *osFibAdapterLinux) needsVrfID() bool { + return true +} + +func (fib *osFibAdapterLinux) setVrfID(vrdID string) error { + // TODO: cast string to int + //fib.vrfID = (uint64)vrdID + // TODO: this is just a hack: + fib.vrfID = uint64(254) + return nil } func newOSFIBLinux(f *FIB) *osFibAdapterLinux { @@ -26,8 +43,8 @@ func newOSFIBLinux(f *FIB) *osFibAdapterLinux { return linuxAdapter } -func (f *osFibAdapterLinux) addPath(pfx bnet.Prefix, paths []*route.FIBPath) error { - route, err := f.createRoute(pfx, paths) +func (fib *osFibAdapterLinux) addPath(pfx bnet.Prefix, paths []*route.FIBPath) error { + route, err := fib.createRoute(pfx, paths) if err != nil { return errors.Wrap(err, "Could not create route from prefix and path: %v") } @@ -45,8 +62,8 @@ func (f *osFibAdapterLinux) addPath(pfx bnet.Prefix, paths []*route.FIBPath) err return nil } -func (f *osFibAdapterLinux) removePath(pfx bnet.Prefix, path *route.FIBPath) error { - nlRoute, err := f.createRoute(pfx, []*route.FIBPath{path}) +func (fib *osFibAdapterLinux) removePath(pfx bnet.Prefix, path *route.FIBPath) error { + nlRoute, err := fib.createRoute(pfx, []*route.FIBPath{path}) if err != nil { return errors.Wrap(err, "Could not create route from prefix and path: %v") } @@ -64,10 +81,14 @@ func (f *osFibAdapterLinux) removePath(pfx bnet.Prefix, path *route.FIBPath) err } // create a route from a prefix and a path -func (f *osFibAdapterLinux) createRoute(pfx bnet.Prefix, paths []*route.FIBPath) (*netlink.Route, error) { +func (fib *osFibAdapterLinux) createRoute(pfx bnet.Prefix, paths []*route.FIBPath) (*netlink.Route, error) { + if fib.vrfID == 0 { + return nil, fmt.Errorf("VRF-ID is not set") + } + route := &netlink.Route{ Dst: pfx.GetIPNet(), - Table: int(f.fib.vrf.ID()), + Table: int(fib.vrfID), Protocol: route.ProtoBio, } diff --git a/protocols/fib/fib_test.go b/protocols/fib/fib_test.go index 6b0adddc3fd097603f15bbad8ee560e72529f428..c3312f79f86d1e9e7d8d489babf64e4570bde7d1 100644 --- a/protocols/fib/fib_test.go +++ b/protocols/fib/fib_test.go @@ -17,7 +17,7 @@ func TestNew(t *testing.T) { } func TestComparePfxPath(t *testing.T) { - v, _ := vrf.NewDefaultVRF() + v, _ := vrf.New("inet.0", 0) f, _ := New(v) tests := []struct {