func TestPathPrependAsnToExistingSeqAttr(t *testing.T) { assert := assert.New(t) origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{ bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint16{65001, 65002, 65003, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, []uint16{65001, 65002, 65003, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65100, 65101, 65102}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65100, 65101})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} bgpmsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) update := bgpmsg.Body.(*bgp.BGPUpdate) UpdatePathAttrs4ByteAs(update) peer := PathCreatePeer() p := NewPath(peer[0], update.NLRI[0], false, update.PathAttributes, time.Now(), false) p.PrependAsn(65000, 1) assert.Equal([]uint32{65000, 65001, 65002, 65003, 65004, 65005, 0, 0, 0}, p.GetAsSeqList()) fmt.Printf("asns: %v", p.GetAsSeqList()) }
func TestTimeTieBreaker(t *testing.T) { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} nlri := bgp.NewIPAddrPrefix(24, "10.10.0.0") updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) peer1 := &PeerInfo{AS: 2, LocalAS: 1, Address: net.IP{1, 1, 1, 1}, ID: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] peer2 := &PeerInfo{AS: 2, LocalAS: 1, Address: net.IP{2, 2, 2, 2}, ID: net.IP{2, 2, 2, 2}} // weaker router-id path2 := ProcessMessage(updateMsg, peer2, time.Now().Add(-1*time.Hour))[0] // older than path1 d := NewDestination(nlri) d.AddNewPath(path1) d.AddNewPath(path2) d.Calculate(nil) assert.Equal(t, len(d.knownPathList), 2) assert.Equal(t, true, d.GetBestPath("").GetSource().ID.Equal(net.IP{2, 2, 2, 2})) // path from peer2 win // this option disables tie breaking by age SelectionOptions.ExternalCompareRouterId = true d = NewDestination(nlri) d.AddNewPath(path1) d.AddNewPath(path2) d.Calculate(nil) assert.Equal(t, len(d.knownPathList), 2) assert.Equal(t, true, d.GetBestPath("").GetSource().ID.Equal(net.IP{1, 1, 1, 1})) // path from peer1 win }
func TestMrtRibEntry(t *testing.T) { aspath1 := []bgp.AsPathParamInterface{ bgp.NewAsPathParam(2, []uint16{1000}), bgp.NewAsPathParam(1, []uint16{1001, 1002}), bgp.NewAsPathParam(2, []uint16{1003, 1004}), } p := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(3), bgp.NewPathAttributeAsPath(aspath1), bgp.NewPathAttributeNextHop("129.1.1.2"), bgp.NewPathAttributeMultiExitDisc(1 << 20), bgp.NewPathAttributeLocalPref(1 << 22), } e1 := NewRibEntry(1, uint32(time.Now().Unix()), p) b1, err := e1.Serialize() if err != nil { t.Fatal(err) } e2 := &RibEntry{} rest, err := e2.DecodeFromBytes(b1) if err != nil { t.Fatal(err) } assert.Equal(t, len(rest), 0) assert.Equal(t, reflect.DeepEqual(e1, e2), true) }
func TestMrtRib(t *testing.T) { aspath1 := []bgp.AsPathParamInterface{ bgp.NewAsPathParam(2, []uint16{1000}), bgp.NewAsPathParam(1, []uint16{1001, 1002}), bgp.NewAsPathParam(2, []uint16{1003, 1004}), } p := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(3), bgp.NewPathAttributeAsPath(aspath1), bgp.NewPathAttributeNextHop("129.1.1.2"), bgp.NewPathAttributeMultiExitDisc(1 << 20), bgp.NewPathAttributeLocalPref(1 << 22), } e1 := NewRibEntry(1, uint32(time.Now().Unix()), p) e2 := NewRibEntry(2, uint32(time.Now().Unix()), p) e3 := NewRibEntry(3, uint32(time.Now().Unix()), p) r1 := NewRib(1, bgp.NewIPAddrPrefix(24, "192.168.0.0"), []*RibEntry{e1, e2, e3}) b1, err := r1.Serialize() if err != nil { t.Fatal(err) } r2 := &Rib{ RouteFamily: bgp.RF_IPv4_UC, } err = r2.DecodeFromBytes(b1) if err != nil { t.Fatal(err) } assert.Equal(t, reflect.DeepEqual(r1, r2), true) }
func (manager *TableManager) AddVrf(name string, id uint32, rd bgp.RouteDistinguisherInterface, importRt, exportRt []bgp.ExtendedCommunityInterface, info *PeerInfo) ([]*Path, error) { if _, ok := manager.Vrfs[name]; ok { return nil, fmt.Errorf("vrf %s already exists", name) } log.WithFields(log.Fields{ "Topic": "Vrf", "Key": name, "Rd": rd, "ImportRt": importRt, "ExportRt": exportRt, }).Debugf("add vrf") manager.Vrfs[name] = &Vrf{ Name: name, Id: id, Rd: rd, ImportRt: importRt, ExportRt: exportRt, } msgs := make([]*Path, 0, len(importRt)) nexthop := "0.0.0.0" for _, target := range importRt { nlri := bgp.NewRouteTargetMembershipNLRI(info.AS, target) pattr := make([]bgp.PathAttributeInterface, 0, 2) pattr = append(pattr, bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP)) pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri})) msgs = append(msgs, NewPath(info, nlri, false, pattr, time.Now(), false)) } return msgs, nil }
//AddLocalProtoRoute is used to add local endpoint to the protocol RIB func (self *OfnetBgp) AddLocalProtoRoute(pathInfo []*OfnetProtoRouteInfo) error { if self.routerIP == "" { //ignoring populating to the bgp rib because //Bgp is not configured. return nil } log.Infof("Received AddLocalProtoRoute to add local endpoint to protocol RIB: %+v", pathInfo) // add routes attrs := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(1), bgp.NewPathAttributeNextHop(pathInfo[0].nextHopIP), bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{self.myBgpAs})}), } paths := []*table.Path{} for _, path := range pathInfo { paths = append(paths, table.NewPath(nil, bgp.NewIPAddrPrefix(32, path.localEpIP), false, attrs, time.Now(), false)) } _, err := self.bgpServer.AddPath("", paths) if err != nil { return err } return nil }
func TestASPathLen(t *testing.T) { assert := assert.New(t) origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{ bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint16{65001, 65002, 65003, 65004, 65004, 65004, 65004, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, []uint16{65001, 65002, 65003, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65100, 65101, 65102}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65100, 65101})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} bgpmsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) update := bgpmsg.Body.(*bgp.BGPUpdate) UpdatePathAttrs4ByteAs(update) peer := PathCreatePeer() p := NewPath(peer[0], update.NLRI[0], false, update.PathAttributes, time.Now(), false) assert.Equal(10, p.GetAsPathLen()) }
func TestImplicitWithdrawCalculate(t *testing.T) { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} nlri := bgp.NewIPAddrPrefix(24, "10.10.0.101") updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] path1.Filter("1", POLICY_DIRECTION_IMPORT) // suppose peer2 has import policy to prepend as-path action := &AsPathPrependAction{ asn: 100, repeat: 1, } path2 := action.Apply(path1.Clone(false), nil) path1.Filter("2", POLICY_DIRECTION_IMPORT) path2.Filter("1", POLICY_DIRECTION_IMPORT) path2.Filter("3", POLICY_DIRECTION_IMPORT) d := NewDestination(nlri) d.AddNewPath(path1) d.AddNewPath(path2) d.Calculate(nil) assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator assert.Equal(t, len(d.GetKnownPathList("2")), 1) assert.Equal(t, d.GetKnownPathList("2")[0].GetAsString(), "100 65001") // peer "2" has modified path {100, 65001} assert.Equal(t, len(d.GetKnownPathList("3")), 1) assert.Equal(t, d.GetKnownPathList("3")[0].GetAsString(), "65001") // peer "3" has original path {65001} assert.Equal(t, len(d.knownPathList), 2) // say, we removed peer2's import policy and // peer1 advertised new path with the same prefix aspathParam = []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001, 65002})} aspath = bgp.NewPathAttributeAsPath(aspathParam) pathAttributes = []bgp.PathAttributeInterface{origin, aspath, nexthop, med} updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) path3 := ProcessMessage(updateMsg, peer1, time.Now())[0] path3.Filter("1", POLICY_DIRECTION_IMPORT) d.AddNewPath(path3) d.Calculate(nil) assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator assert.Equal(t, len(d.GetKnownPathList("2")), 1) assert.Equal(t, d.GetKnownPathList("2")[0].GetAsString(), "65001 65002") // peer "2" has new original path {65001, 65002} assert.Equal(t, len(d.GetKnownPathList("3")), 1) assert.Equal(t, d.GetKnownPathList("3")[0].GetAsString(), "65001 65002") // peer "3" has new original path {65001, 65002} assert.Equal(t, len(d.knownPathList), 1) }
func createPathFromIPRouteMessage(m *zebra.Message) *table.Path { header := m.Header body := m.Body.(*zebra.IPRouteBody) family := bgp.RF_IPv6_UC if header.Command == zebra.IPV4_ROUTE_ADD || header.Command == zebra.IPV4_ROUTE_DELETE { family = bgp.RF_IPv4_UC } var nlri bgp.AddrPrefixInterface pattr := make([]bgp.PathAttributeInterface, 0) var mpnlri *bgp.PathAttributeMpReachNLRI var isWithdraw bool = header.Command == zebra.IPV4_ROUTE_DELETE || header.Command == zebra.IPV6_ROUTE_DELETE origin := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP) pattr = append(pattr, origin) log.WithFields(log.Fields{ "Topic": "Zebra", "RouteType": body.Type.String(), "Flag": body.Flags.String(), "Message": body.Message, "Prefix": body.Prefix, "PrefixLength": body.PrefixLength, "Nexthop": body.Nexthops, "IfIndex": body.Ifindexs, "Metric": body.Metric, "Distance": body.Distance, "api": header.Command.String(), }).Debugf("create path from ip route message.") switch family { case bgp.RF_IPv4_UC: nlri = bgp.NewIPAddrPrefix(body.PrefixLength, body.Prefix.String()) nexthop := bgp.NewPathAttributeNextHop(body.Nexthops[0].String()) pattr = append(pattr, nexthop) case bgp.RF_IPv6_UC: nlri = bgp.NewIPv6AddrPrefix(body.PrefixLength, body.Prefix.String()) mpnlri = bgp.NewPathAttributeMpReachNLRI(body.Nexthops[0].String(), []bgp.AddrPrefixInterface{nlri}) pattr = append(pattr, mpnlri) default: log.WithFields(log.Fields{ "Topic": "Zebra", }).Errorf("unsupport address family: %s", family) return nil } med := bgp.NewPathAttributeMultiExitDisc(body.Metric) pattr = append(pattr, med) path := table.NewPath(nil, nlri, isWithdraw, pattr, time.Now(), false) path.SetIsFromExternal(true) return path }
func TestCalculate2(t *testing.T) { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} nlri := bgp.NewIPAddrPrefix(24, "10.10.0.0") // peer1 sends normal update message 10.10.0.0/24 update1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(update1, peer1, time.Now())[0] d := NewDestination(nlri) d.AddNewPath(path1) d.Calculate(nil) // suppose peer2 sends grammaatically correct but semantically flawed update message // which has a withdrawal nlri not advertised before update2 := bgp.NewBGPUpdateMessage([]*bgp.IPAddrPrefix{nlri}, pathAttributes, nil) peer2 := &PeerInfo{AS: 2, Address: net.IP{2, 2, 2, 2}} path2 := ProcessMessage(update2, peer2, time.Now())[0] assert.Equal(t, path2.IsWithdraw, true) d.AddWithdraw(path2) d.Calculate(nil) // we have a path from peer1 here assert.Equal(t, len(d.knownPathList), 1) // after that, new update with the same nlri comes from peer2 update3 := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) path3 := ProcessMessage(update3, peer2, time.Now())[0] assert.Equal(t, path3.IsWithdraw, false) d.AddNewPath(path3) d.Calculate(nil) // this time, we have paths from peer1 and peer2 assert.Equal(t, len(d.knownPathList), 2) // now peer3 sends normal update message 10.10.0.0/24 peer3 := &PeerInfo{AS: 3, Address: net.IP{3, 3, 3, 3}} update4 := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) path4 := ProcessMessage(update4, peer3, time.Now())[0] d.AddNewPath(path4) d.Calculate(nil) // we must have paths from peer1, peer2 and peer3 assert.Equal(t, len(d.knownPathList), 3) }
func (bs *BgpService) AddPath(route string) error { attrs := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(0), bgp.NewPathAttributeNextHop("0.0.0.0"), } if _, err := bs.bgp.AddPath("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(32, route), false, attrs, time.Now(), false)}); err != nil { return fmt.Errorf("[bgp] Error adding bgp path. %v", err) } return nil }
func createPathFromIPRouteMessage(m *zebra.Message, peerInfo *table.PeerInfo) *table.Path { header := m.Header body := m.Body.(*zebra.IPRouteBody) isV4 := header.Command == zebra.IPV4_ROUTE_ADD || header.Command == zebra.IPV4_ROUTE_DELETE var nlri bgp.AddrPrefixInterface pattr := make([]bgp.PathAttributeInterface, 0) var mpnlri *bgp.PathAttributeMpReachNLRI var isWithdraw bool = header.Command == zebra.IPV4_ROUTE_DELETE || header.Command == zebra.IPV6_ROUTE_DELETE origin := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP) pattr = append(pattr, origin) log.WithFields(log.Fields{ "Topic": "Zebra", "RouteType": body.Type.String(), "Flag": body.Flags.String(), "Message": body.Message, "Prefix": body.Prefix, "PrefixLength": body.PrefixLength, "Nexthop": body.Nexthops, "IfIndex": body.Ifindexs, "Metric": body.Metric, "Distance": body.Distance, "api": header.Command.String(), }).Debugf("create path from ip route message.") if isV4 { nlri = bgp.NewIPAddrPrefix(body.PrefixLength, body.Prefix.String()) nexthop := bgp.NewPathAttributeNextHop(body.Nexthops[0].String()) pattr = append(pattr, nexthop) } else { nlri = bgp.NewIPv6AddrPrefix(body.PrefixLength, body.Prefix.String()) mpnlri = bgp.NewPathAttributeMpReachNLRI(body.Nexthops[0].String(), []bgp.AddrPrefixInterface{nlri}) pattr = append(pattr, mpnlri) } med := bgp.NewPathAttributeMultiExitDisc(body.Metric) pattr = append(pattr, med) p := table.NewPath(peerInfo, nlri, isWithdraw, pattr, time.Now(), false) p.SetIsFromExternal(true) return p }
func updateMsgP2() *bgp.BGPMessage { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65100})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.100.1") med := bgp.NewPathAttributeMultiExitDisc(100) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "20.20.20.0")} return bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) }
func extractOrigin(args []string) ([]string, bgp.PathAttributeInterface, error) { typ := bgp.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE for idx, arg := range args { if arg == "origin" && len(args) > (idx+1) { switch args[idx+1] { case "igp": typ = bgp.BGP_ORIGIN_ATTR_TYPE_IGP case "egp": typ = bgp.BGP_ORIGIN_ATTR_TYPE_EGP case "incomplete": default: return nil, nil, fmt.Errorf("invalid origin type. expect [igp|egp|incomplete] but %s", args[idx+1]) } args = append(args[:idx], args[idx+2:]...) break } } return args, bgp.NewPathAttributeOrigin(uint8(typ)), nil }
//DeleteLocalProtoRoute withdraws local endpoints from protocol RIB func (self *OfnetBgp) DeleteLocalProtoRoute(pathInfo []*OfnetProtoRouteInfo) error { log.Infof("Received DeleteLocalProtoRoute to withdraw local endpoint to protocol RIB: %v", pathInfo) attrs := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(1), bgp.NewPathAttributeNextHop(pathInfo[0].nextHopIP), bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{self.myBgpAs})}), } paths := []*table.Path{} for _, path := range pathInfo { paths = append(paths, table.NewPath(nil, bgp.NewIPAddrPrefix(32, path.localEpIP), true, attrs, time.Now(), false)) } if err := self.bgpServer.DeletePath(nil, bgp.RF_IPv4_UC, "", paths); err != nil { return err } return nil }
func updateMsgD1() *bgp.BGPMessage { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65000})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate)) return updateMsg }
//DeleteLocalProtoRoute withdraws local endpoints from protocol RIB func (self *OfnetBgp) DeleteLocalProtoRoute(pathInfo *OfnetProtoRouteInfo) error { log.Infof("Received DeleteLocalProtoRoute to withdraw local endpoint to protocol RIB: %v", pathInfo) path := &api.Path{ Pattrs: make([][]byte, 0), } //form appropraite path attributes for path to be withdrawn nlri := bgp.NewIPAddrPrefix(32, pathInfo.localEpIP) path.Nlri, _ = nlri.Serialize() origin, _ := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_EGP).Serialize() path.Pattrs = append(path.Pattrs, origin) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{self.myBgpAs})} aspath, _ := bgp.NewPathAttributeAsPath(aspathParam).Serialize() path.Pattrs = append(path.Pattrs, aspath) n, _ := bgp.NewPathAttributeNextHop(pathInfo.nextHopIP).Serialize() path.Pattrs = append(path.Pattrs, n) path.IsWithdraw = true //paths := []*api.Path{path} arg := &api.DeletePathRequest{ Resource: api.Resource_GLOBAL, Path: path, } //send arguement stream client := api.NewGobgpApiClient(self.cc) if client == nil { log.Errorf("Gobgpapi stream invalid") return nil } _, err := client.DeletePath(context.Background(), arg) if err != nil { log.Errorf("Fail to enforce Modpathi: %v", err) return err } return nil }
func TestPathPrependAsnToNewAsPathAttr(t *testing.T) { assert := assert.New(t) origin := bgp.NewPathAttributeOrigin(0) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") pathAttributes := []bgp.PathAttributeInterface{ origin, nexthop, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} bgpmsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) update := bgpmsg.Body.(*bgp.BGPUpdate) UpdatePathAttrs4ByteAs(update) peer := PathCreatePeer() p := NewPath(peer[0], update.NLRI[0], false, update.PathAttributes, time.Now(), false) asn := uint32(65000) p.PrependAsn(asn, 1) assert.Equal([]uint32{asn}, p.GetAsSeqList()) }
func TestBMP(t *testing.T) { aspath1 := []bgp.AsPathParamInterface{ bgp.NewAs4PathParam(2, []uint32{1000000}), bgp.NewAs4PathParam(1, []uint32{1000001, 1002}), bgp.NewAs4PathParam(2, []uint32{1003, 100004}), } mp_nlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(100, "fe80:1234:1234:5667:8967:af12:8912:1023")} p := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(3), bgp.NewPathAttributeAsPath(aspath1), bgp.NewPathAttributeMpUnreachNLRI(mp_nlri), } w := []*bgp.IPAddrPrefix{} n := []*bgp.IPAddrPrefix{} msg := bgp.NewBGPUpdateMessage(w, p, n) pList := ProcessMessage(msg, peerR1(), time.Now()) CreateUpdateMsgFromPaths(pList) }
func updateMsgD3() *bgp.BGPMessage { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65100})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.150.1") med := bgp.NewPathAttributeMultiExitDisc(100) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "30.30.30.0")} w1 := bgp.NewIPAddrPrefix(23, "40.40.40.0") withdrawnRoutes := []*bgp.IPAddrPrefix{w1} updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate)) return updateMsg }
func TestCalculate(t *testing.T) { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} nlri := bgp.NewIPAddrPrefix(24, "10.10.0.101") updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] path1.Filter("1", POLICY_DIRECTION_IMPORT) action := &AsPathPrependAction{ asn: 100, repeat: 10, } path2 := action.Apply(path1.Clone(false), nil) path1.Filter("2", POLICY_DIRECTION_IMPORT) path2.Filter("1", POLICY_DIRECTION_IMPORT) d := NewDestination(nlri) d.AddNewPath(path1) d.AddNewPath(path2) d.Calculate([]string{"1", "2"}) assert.Equal(t, len(d.GetKnownPathList("1")), 0) assert.Equal(t, len(d.GetKnownPathList("2")), 1) assert.Equal(t, len(d.knownPathList), 2) d.AddWithdraw(path1.Clone(true)) d.Calculate([]string{"1", "2"}) assert.Equal(t, len(d.GetKnownPathList("1")), 0) assert.Equal(t, len(d.GetKnownPathList("2")), 0) assert.Equal(t, len(d.knownPathList), 0) }
func TestPathPrependAsnToFullPathAttr(t *testing.T) { assert := assert.New(t) origin := bgp.NewPathAttributeOrigin(0) asns := make([]uint16, 255) for i, _ := range asns { asns[i] = 65000 + uint16(i) } aspathParam := []bgp.AsPathParamInterface{ bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, asns), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, []uint16{65001, 65002, 65003, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65100, 65101, 65102}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65100, 65101})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} bgpmsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) update := bgpmsg.Body.(*bgp.BGPUpdate) UpdatePathAttrs4ByteAs(update) peer := PathCreatePeer() p := NewPath(peer[0], update.NLRI[0], false, update.PathAttributes, time.Now(), false) expected := []uint32{65000, 65000} for _, v := range asns { expected = append(expected, uint32(v)) } p.PrependAsn(65000, 2) assert.Equal(append(expected, []uint32{0, 0, 0}...), p.GetAsSeqList()) fmt.Printf("asns: %v", p.GetAsSeqList()) }
func TestMonitor(test *testing.T) { assert := assert.New(test) s := NewBgpServer() go s.Serve() s.Start(&config.Global{ Config: config.GlobalConfig{ As: 1, RouterId: "1.1.1.1", Port: 10179, }, }) n := &config.Neighbor{ Config: config.NeighborConfig{ NeighborAddress: "127.0.0.1", PeerAs: 2, }, Transport: config.Transport{ Config: config.TransportConfig{ PassiveMode: true, }, }, } if err := s.AddNeighbor(n); err != nil { log.Fatal(err) } t := NewBgpServer() go t.Serve() t.Start(&config.Global{ Config: config.GlobalConfig{ As: 2, RouterId: "2.2.2.2", Port: -1, }, }) m := &config.Neighbor{ Config: config.NeighborConfig{ NeighborAddress: "127.0.0.1", PeerAs: 1, }, Transport: config.Transport{ Config: config.TransportConfig{ RemotePort: 10179, }, }, } if err := t.AddNeighbor(m); err != nil { log.Fatal(err) } for { time.Sleep(time.Second) if t.GetNeighbor(false)[0].State.SessionState == config.SESSION_STATE_ESTABLISHED { break } } w := s.Watch(WatchBestPath()) attrs := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(0), bgp.NewPathAttributeNextHop("10.0.0.1"), } if _, err := t.AddPath("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.0.0.0"), false, attrs, time.Now(), false)}); err != nil { log.Fatal(err) } ev := <-w.Event() b := ev.(*WatchEventBestPath) assert.Equal(len(b.PathList), 1) assert.Equal(b.PathList[0].GetNlri().String(), "10.0.0.0/24") assert.Equal(b.PathList[0].IsWithdraw, false) if _, err := t.AddPath("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.0.0.0"), true, attrs, time.Now(), false)}); err != nil { log.Fatal(err) } ev = <-w.Event() b = ev.(*WatchEventBestPath) assert.Equal(len(b.PathList), 1) assert.Equal(b.PathList[0].GetNlri().String(), "10.0.0.0/24") assert.Equal(b.PathList[0].IsWithdraw, true) }
/* Bgp serve routine does the following: 1) Creates inb01 router port 2) Add MyBgp endpoint 3) Kicks off routines to monitor route updates and peer state */ func (self *OfnetBgp) StartProtoServer(routerInfo *OfnetProtoRouterInfo) error { log.Infof("Starting the Bgp Server with %v", routerInfo) //go routine to start gobgp server var len uint var err error self.routerIP, len, err = ParseCIDR(routerInfo.RouterIP) as, _ := strconv.Atoi(routerInfo.As) self.myBgpAs = uint32(as) log.Infof("Starting the Bgp Server for AS %v", self.myBgpAs) self.modRibCh = make(chan *api.Path, 16) self.advPathCh = make(chan *api.Path, 16) timeout := grpc.WithTimeout(time.Second) conn, err := grpc.Dial("127.0.0.1:50051", timeout, grpc.WithBlock(), grpc.WithInsecure()) if err != nil { log.Infof("GRPC timeout") log.Fatal(err) } self.cc = conn defer self.cc.Close() client := api.NewGobgpApiClient(self.cc) if client == nil { log.Errorf("Invalid Gobgpapi client") return errors.New("Error creating Gobgpapiclient") } path := &api.Path{ Pattrs: make([][]byte, 0), } path.Nlri, _ = bgp.NewIPAddrPrefix(uint8(32), self.routerIP).Serialize() n, _ := bgp.NewPathAttributeNextHop("0.0.0.0").Serialize() path.Pattrs = append(path.Pattrs, n) origin, _ := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE).Serialize() path.Pattrs = append(path.Pattrs, origin) log.Infof("Creating the loopback port ") err = self.agent.ovsDriver.CreatePort(self.intfName, "internal", 1) if err != nil { log.Errorf("Error creating the port: %v", err) } defer self.agent.ovsDriver.DeletePort(self.intfName) intfIP := fmt.Sprintf("%s/%d", self.routerIP, len) log.Infof("Creating inb01 with ", intfIP) ofPortno, _ := self.agent.ovsDriver.GetOfpPortNo(self.intfName) link, err := netlink.LinkByName(self.intfName) if err != nil { log.Errorf("error finding link by name %v", self.intfName) return err } linkIP, err := netlink.ParseAddr(intfIP) if err != nil { log.Errorf("invalid ip: %s", intfIP) return err } netlink.AddrAdd(link, linkIP) netlink.LinkSetUp(link) if link == nil || ofPortno == 0 { log.Errorf("Error fetching %v/%v/%v information", self.intfName, link, ofPortno) return errors.New("Unable to fetch inb01 info") } intf, _ := net.InterfaceByName(self.intfName) log.Infof("routerIP ", self.routerIP) epid := self.agent.getEndpointIdByIpVrf(net.ParseIP(self.routerIP), "default") log.Infof("Create VRF ") _, ok := self.agent.createVrf("default") if !ok { log.Errorf("Error Creating default vrf for Bgp") return errors.New("Error creating default vrf") } epreg := &OfnetEndpoint{ EndpointID: epid, EndpointType: "internal-bgp", IpAddr: net.ParseIP(self.routerIP), IpMask: net.ParseIP("255.255.255.255"), Vrf: "default", // FIXME set VRF correctly MacAddrStr: intf.HardwareAddr.String(), //link.Attrs().HardwareAddr.String(), Vlan: 1, PortNo: ofPortno, Timestamp: time.Now(), } // Add the endpoint to local routing table self.agent.endpointDb[epid] = epreg //log.Infof("self.agent.endpointDb[epid] %v " , self.agent.endpointDb[epid] ) self.agent.localEndpointDb[epreg.PortNo] = epreg fmt.Println(epreg) err = self.agent.datapath.AddLocalEndpoint(*epreg) //Add bgp router id as well bgpGlobalCfg := &bgpconf.Global{} setDefaultGlobalConfigValues(bgpGlobalCfg) bgpGlobalCfg.Config.RouterId = self.routerIP bgpGlobalCfg.Config.As = self.myBgpAs //self.bgpServer.SetGlobalType(*bgpGlobalCfg) _, err2 := client.StartServer(context.Background(), &api.StartServerRequest{ Global: &api.Global{ As: uint32(self.myBgpAs), RouterId: self.routerIP, ListenPort: int32(epreg.PortNo), ListenAddresses: []string{self.routerIP}, MplsLabelMin: uint32(16000), MplsLabelMax: uint32(1048575), }, }) log.Info("BGP -StartServer ERR %v", err2) self.advPathCh <- path log.Infof("start monitoring ") //monitor route updates from peer go self.monitorBest() //monitor peer state go self.monitorPeer() self.start <- true for { select { case p := <-self.modRibCh: err = self.modRib(p) if err != nil { log.Error("failed to mod rib: ", err) } case <-self.stop: return nil } } }
// Test adding/deleting Vlrouter routes func TestOfnetBgpVlrouteAddDelete(t *testing.T) { neighborAs := "500" peer := "50.1.1.3" routerIP := "50.1.1.2/24" as := "65002" //Add Bgp neighbor and check if it is successful for i := 0; i < NUM_VLRTR_AGENT; i++ { err := vlrtrAgents[i].AddBgp(routerIP, as, neighborAs, peer) time.Sleep(5 * time.Second) if err != nil { t.Errorf("Error adding Bgp Neighbor: %v", err) return } attrs := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(1), bgp.NewPathAttributeNextHop("50.1.1.3"), bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65002})}), } path := table.NewPath(nil, bgp.NewIPAddrPrefix(32, "20.20.20.20"), false, attrs, time.Now(), false) vlrtrAgents[i].protopath.ModifyProtoRib(path) log.Infof("Adding path to the Bgp Rib") time.Sleep(2 * time.Second) // verify flow entry exists brName := "vlrtrBridge" + fmt.Sprintf("%d", i) flowList, err := ofctlFlowDump(brName) if err != nil { t.Errorf("Error getting flow entries. Err: %v", err) } ipFlowMatch := fmt.Sprintf("priority=100,ip,nw_dst=20.20.20.20") ipTableId := IP_TBL_ID if !ofctlFlowMatch(flowList, ipTableId, ipFlowMatch) { t.Errorf("Could not find the route %s on ovs %s", ipFlowMatch, brName) return } log.Infof("Found ipflow %s on ovs %s", ipFlowMatch, brName) // withdraw the route path.IsWithdraw = true vlrtrAgents[i].protopath.ModifyProtoRib(path) log.Infof("Withdrawing route from BGP rib") // verify flow entry exists brName = "vlrtrBridge" + fmt.Sprintf("%d", i) flowList, err = ofctlFlowDump(brName) if err != nil { t.Errorf("Error getting flow entries. Err: %v", err) } ipFlowMatch = fmt.Sprintf("priority=100,ip,nw_dst=20.20.20.20") ipTableId = IP_TBL_ID if ofctlFlowMatch(flowList, ipTableId, ipFlowMatch) { t.Errorf("Found the route %s on ovs %s which was withdrawn", ipFlowMatch, brName) return } log.Infof("ipflow %s on ovs %s has been deleted from OVS", ipFlowMatch, brName) } }
func TestMultipath(t *testing.T) { UseMultiplePaths.Enabled = true origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65000})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.150.1") med := bgp.NewPathAttributeMultiExitDisc(100) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}, ID: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] peer2 := &PeerInfo{AS: 2, Address: net.IP{2, 2, 2, 2}, ID: net.IP{2, 2, 2, 2}} med = bgp.NewPathAttributeMultiExitDisc(100) nexthop = bgp.NewPathAttributeNextHop("192.168.150.2") pathAttributes = []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) path2 := ProcessMessage(updateMsg, peer2, time.Now())[0] d := NewDestination(nlri[0]) d.AddNewPath(path1) d.AddNewPath(path2) best, w, multi := d.Calculate([]string{GLOBAL_RIB_NAME}) assert.Equal(t, len(best), 1) assert.Equal(t, len(w), 0) assert.Equal(t, len(multi), 2) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2) path3 := path2.Clone(true) d.AddWithdraw(path3) best, w, multi = d.Calculate([]string{GLOBAL_RIB_NAME}) assert.Equal(t, len(best), 1) assert.Equal(t, len(w), 1) assert.Equal(t, len(multi), 1) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 1) peer3 := &PeerInfo{AS: 3, Address: net.IP{3, 3, 3, 3}, ID: net.IP{3, 3, 3, 3}} med = bgp.NewPathAttributeMultiExitDisc(50) nexthop = bgp.NewPathAttributeNextHop("192.168.150.3") pathAttributes = []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) path4 := ProcessMessage(updateMsg, peer3, time.Now())[0] d.AddNewPath(path4) best, w, multi = d.Calculate([]string{GLOBAL_RIB_NAME}) assert.Equal(t, len(best), 1) assert.Equal(t, len(w), 0) assert.Equal(t, len(multi), 1) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2) nexthop = bgp.NewPathAttributeNextHop("192.168.150.2") pathAttributes = []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) path5 := ProcessMessage(updateMsg, peer2, time.Now())[0] d.AddNewPath(path5) best, w, multi = d.Calculate([]string{GLOBAL_RIB_NAME}) assert.Equal(t, len(best), 1) assert.Equal(t, len(w), 0) assert.Equal(t, len(multi), 2) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 3) UseMultiplePaths.Enabled = false }
func createRequestFromIPRouteMessage(m *zebra.Message) *api.AddPathRequest { header := m.Header body := m.Body.(*zebra.IPRouteBody) family := bgp.RF_IPv6_UC if header.Command == zebra.IPV4_ROUTE_ADD || header.Command == zebra.IPV4_ROUTE_DELETE { family = bgp.RF_IPv4_UC } var nlri bgp.AddrPrefixInterface pattr := make([]bgp.PathAttributeInterface, 0) var mpnlri *bgp.PathAttributeMpReachNLRI var isWithdraw bool = header.Command == zebra.IPV4_ROUTE_DELETE || header.Command == zebra.IPV6_ROUTE_DELETE origin := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP) pattr = append(pattr, origin) log.WithFields(log.Fields{ "Topic": "Zebra", "RouteType": body.Type.String(), "Flag": body.Flags.String(), "Message": body.Message, "Prefix": body.Prefix, "PrefixLength": body.PrefixLength, "Nexthop": body.Nexthops, "IfIndex": body.Ifindexs, "Metric": body.Metric, "Distance": body.Distance, "api": header.Command.String(), }).Debugf("create path from ip route message.") switch family { case bgp.RF_IPv4_UC: nlri = bgp.NewIPAddrPrefix(body.PrefixLength, body.Prefix.String()) nexthop := bgp.NewPathAttributeNextHop(body.Nexthops[0].String()) pattr = append(pattr, nexthop) case bgp.RF_IPv6_UC: nlri = bgp.NewIPv6AddrPrefix(body.PrefixLength, body.Prefix.String()) mpnlri = bgp.NewPathAttributeMpReachNLRI(body.Nexthops[0].String(), []bgp.AddrPrefixInterface{nlri}) pattr = append(pattr, mpnlri) default: log.WithFields(log.Fields{ "Topic": "Zebra", }).Errorf("unsupport address family: %s", family) return nil } med := bgp.NewPathAttributeMultiExitDisc(body.Metric) pattr = append(pattr, med) binPattrs := make([][]byte, 0, len(pattr)) for _, a := range pattr { bin, _ := a.Serialize() binPattrs = append(binPattrs, bin) } binNlri, _ := nlri.Serialize() path := &api.Path{ Nlri: binNlri, Pattrs: binPattrs, IsWithdraw: isWithdraw, Family: uint32(family), IsFromExternal: true, } return &api.AddPathRequest{ Resource: api.Resource_GLOBAL, Path: path, } }
func parseRouteToGobgp(route ovsdb.RowUpdate, nexthops map[string]ovsdb.Row) (*api.Path, bool, bool, error) { var nlri bgp.AddrPrefixInterface path := &api.Path{ IsFromExternal: true, Pattrs: make([][]byte, 0), } isWithdraw := false isFromGobgp := false prefix := route.New.Fields["prefix"].(string) safi := route.New.Fields["sub_address_family"].(string) afi := route.New.Fields["address_family"].(string) m := route.New.Fields["metric"].(float64) attrs := route.New.Fields["path_attributes"].(ovsdb.OvsMap).GoMap if attrs["IsFromGobgp"] == "true" { isFromGobgp = true } nh := make([]interface{}, 0) nhId, ok := route.New.Fields["bgp_nexthops"].(ovsdb.UUID) if ok { for id, n := range nexthops { if id == nhId.GoUUID { nh = append(nh, n.Fields["ip_address"]) } } } nexthop := "0.0.0.0" if afi == "ipv6" { nexthop = "::" } if len(nh) == 0 { log.Debug("nexthop addres does not exist") } else if len(nh) == 1 { if net.ParseIP(nh[0].(string)) == nil { return nil, isWithdraw, isFromGobgp, fmt.Errorf("invalid nexthop address") } else { nexthop = nh[0].(string) } } else { return nil, isWithdraw, isFromGobgp, fmt.Errorf("route has multiple nexthop address") } med, _ := bgp.NewPathAttributeMultiExitDisc(uint32(m)).Serialize() path.Pattrs = append(path.Pattrs, med) lpref, err := strconv.Atoi(attrs["BGP_loc_pref"].(string)) if err != nil { return nil, isWithdraw, isFromGobgp, err } localPref, _ := bgp.NewPathAttributeLocalPref(uint32(lpref)).Serialize() path.Pattrs = append(path.Pattrs, localPref) var origin_t int switch attrs["BGP_origin"].(string) { case "i": origin_t = bgp.BGP_ORIGIN_ATTR_TYPE_IGP case "e": origin_t = bgp.BGP_ORIGIN_ATTR_TYPE_EGP case "?": origin_t = bgp.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE default: return nil, isWithdraw, isFromGobgp, fmt.Errorf("invalid origin") } origin, _ := bgp.NewPathAttributeOrigin(uint8(origin_t)).Serialize() path.Pattrs = append(path.Pattrs, origin) switch afi { case "ipv4", "ipv6": ip, net, err := net.ParseCIDR(prefix) if err != nil { return nil, isWithdraw, isFromGobgp, err } ones, _ := net.Mask.Size() if afi == "ipv4" { if ip.To4() == nil { return nil, isWithdraw, isFromGobgp, fmt.Errorf("invalid ipv4 prefix") } nlri = bgp.NewIPAddrPrefix(uint8(ones), ip.String()) } else { if ip.To16() == nil { return nil, isWithdraw, isFromGobgp, fmt.Errorf("invalid ipv6 prefix") } nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String()) } default: return nil, isWithdraw, isFromGobgp, fmt.Errorf("unsupported address family: %s", afi) } if afi == "ipv4" && safi == "unicast" { path.Nlri, _ = nlri.Serialize() n, _ := bgp.NewPathAttributeNextHop(nexthop).Serialize() path.Pattrs = append(path.Pattrs, n) } else { mpreach, _ := bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri}).Serialize() path.Pattrs = append(path.Pattrs, mpreach) } if attrs["BGP_flags"].(string) == "512" { isWithdraw = true } return path, isWithdraw, isFromGobgp, nil }
//AddLocalProtoRoute is used to add local endpoint to the protocol RIB func (self *OfnetBgp) AddLocalProtoRoute(pathInfo *OfnetProtoRouteInfo) error { log.Infof("Received AddLocalProtoRoute to add local endpoint to protocol RIB: %v", pathInfo) if self.routerIP == "" { //ignoring populating to the bgp rib because //Bgp is not configured. return nil } path := &api.Path{ Pattrs: make([][]byte, 0), SourceAsn: self.myBgpAs, } aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{self.myBgpAs})} aspath, _ := bgp.NewPathAttributeAsPath(aspathParam).Serialize() path.Pattrs = append(path.Pattrs, aspath) // form the path structure with appropriate path attributes nlri := bgp.NewIPAddrPrefix(32, pathInfo.localEpIP) path.Nlri, _ = nlri.Serialize() origin, _ := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_EGP).Serialize() path.Pattrs = append(path.Pattrs, origin) log.Infof("Received AddLocalProtoRoute aspath: %v", aspath) mpls, err := bgp.ParseMPLSLabelStack("3") if err != nil { return nil } var nlri2 bgp.AddrPrefixInterface nlri2 = bgp.NewLabeledIPAddrPrefix(32, pathInfo.localEpIP, *mpls) mpreach, _ := bgp.NewPathAttributeMpReachNLRI(pathInfo.nextHopIP, []bgp.AddrPrefixInterface{nlri2}).Serialize() log.Infof("Received AddLocalProtoRoute nlri2: %v, mpreach: %v", nlri2, mpreach) path.Pattrs = append(path.Pattrs, mpreach) //path.Pattrs = append(path.Pattrs, n) arg := &api.AddPathRequest{ Resource: api.Resource_GLOBAL, VrfId: "default", Path: path, } log.Infof("BGP - arg %v ", arg) // add routes /* prefix := pathInfo.localEpIP log.Infof("BGP - Prefix %v " , prefix ) path2, err := cmd.ParsePath(bgp.RF_IPv4_MPLS, []string{"10.200.1.25/32", "3"}) log.Infof("BGP - Path2 %v " , path2 ) log.Infof("BGP - Err %v " , err ) req := bgpserver.NewGrpcRequest(bgpserver.REQ_ADD_PATH, "", bgp.RouteFamily(0), &api.AddPathRequest{ Resource: api.Resource_GLOBAL, Path: path2, }) self.bgpServer.GrpcReqCh <- req res := <-req.ResponseCh if err := res.Err(); err != nil { log.Fatal(err) log.Infof("BGP - Err %v " , err) } */ //send arguement stream client := api.NewGobgpApiClient(self.cc) if client == nil { log.Infof("Gobgpapi stream invalid") return nil } stream, err := client.AddPath(context.Background(), arg) if err != nil { log.Infof("Fail to enforce Modpath: %v %v", err, stream) return err } return nil }