osrg / gobgp

BGP implemented in the Go Programming Language
https://osrg.github.io/gobgp/
Apache License 2.0
3.67k stars 699 forks source link

Equal Cost Multipath Routing without Zebra #2214

Open cnjinshuai opened 5 years ago

cnjinshuai commented 5 years ago
R1: GoBGP R2: GoBGP R3: GoBGP R4: sdn controller(monitor global rib),need to get the best route of R1 and config to my network. +-------------+ R4 ID: 4.4.4.4 AS: 65001 +-------------+ .1/24
10.1.1.0/24
.3/24
+-------------+                     +-------------+
| R1          | .1/24         .2/24 | R2          |
| ID: 1.1.1.1 |---------------------| ID: 2.2.2.2 |
| AS: 65001   |   192.168.12.0/24   | AS: 65000   |
+-------------+                     +-------------+
    | .1/24
    |
    | 192.168.13.0/24
    |
    | .3/24
+-------------+
| R3          |
| ID: 3.3.3.3 |
| AS: 65000   |
+-------------+

step1: R2> gobgp global rib -a ipv4 add 10.23.1.0/24 R3> gobgp global rib -a ipv4 add 10.23.1.0/24 R4 has monitored 2 routes one by one, but them isn't best route, how to judge if 10.23.1.0/24 is ecmp route? step2: R2> gobgp global rib -a ipv4 del 10.23.1.0/24 R4 has monitored 1 route(nexthop is R3), but R4 don't kown if there are any new 10.23.1.0/24 route coming.

step3: R2> gobgp global rib -a ipv4 add 10.23.1.0/24 med 100 R3> gobgp global rib -a ipv4 add 10.23.1.0/24 med 10 R4 can monitor the best route(next hop R3).

Is there a more friendly way to get the best route and ecmp route in the V3 except https://github.com/osrg/gobgp/issues/1958

ljluestc commented 3 months ago

package main

import (
    "context"
    "fmt"
    "log"
    "github.com/osrg/gobgp/api"
    "google.golang.org/grpc"
)

func main() {
    // Connect to GoBGP gRPC API
    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("failed to connect: %v", err)
    }
    defer conn.Close()
    client := api.NewBGPClient(conn)

    // Fetch global RIB
    req := &api.GetRibRequest{
        Table: api.RIB_TYPE_GLOBAL,
        Family: api.Family_IPV4_UNICAST,
    }
    resp, err := client.GetRib(context.Background(), req)
    if err != nil {
        log.Fatalf("failed to get RIB: %v", err)
    }

    // Check for ECMP routes
    for _, path := range resp.GetDestinations() {
        if path.GetPrefix() == "10.23.1.0/24" {
            fmt.Printf("Routes for 10.23.1.0/24:\n")
            for _, p := range path.GetPathList() {
                fmt.Printf("Path: %v\n", p)
            }
            // Check if there are multiple ECMP paths
            if len(path.GetPathList()) > 1 {
                fmt.Println("ECMP detected")
            }
        }
    }
}