1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
# Using SR Policy in GoBGP library mode
This page explains how to use GoBGP for Injecting SR Policy. This example shows how to build new SR Policy NLRI and associated with NLRI attributes. This attributes are sent as Tunnel Encapsulation of type 15 (SR Policy) SUB TLV's.
## Contents
- [Basic SR Policy Example](#basic-srpolicy-example)
## Basic SR Policy Example
```go
package main
import (
"context"
"encoding/binary"
"fmt"
"net"
"os"
"github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/any"
api "github.com/osrg/gobgp/api"
toolbox "github.com/sbezverk/gobgptoolbox"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/anypb"
)
func AddSRPolicy(client api.GobgpApiClient) error {
nlrisr, _ := ptypes.MarshalAny(&api.SRPolicyNLRI{
Length: 96,
Distinguisher: 2,
Color: 99,
Endpoint: net.ParseIP("10.0.0.15").To4(),
})
// Origin attribute
origin, _ := ptypes.MarshalAny(&api.OriginAttribute{
Origin: 0,
})
// Next hop attribute
nh, _ := ptypes.MarshalAny(&api.NextHopAttribute{
NextHop: net.ParseIP("192.168.20.1").To4().String(),
})
// Extended communities attribute
toolbox.MarshalRTFromString("")
rtm, err := toolbox.MarshalRTFromString("10.0.0.8:0")
if err != nil {
return err
}
rt, _ := ptypes.MarshalAny(&api.ExtendedCommunitiesAttribute{
Communities: []*any.Any{rtm},
})
// Tunnel Encapsulation Type 15 (SR Policy) sub tlvs
s := make([]byte, 4)
binary.BigEndian.PutUint32(s, 24321)
sid, err := ptypes.MarshalAny(&api.SRBindingSID{
SFlag: true,
IFlag: false,
Sid: s,
})
if err != nil {
return err
}
bsid, err := ptypes.MarshalAny(&api.TunnelEncapSubTLVSRBindingSID{
Bsid: sid,
})
if err != nil {
return err
}
segment, err := ptypes.MarshalAny(&api.SegmentTypeA{
Flags: &api.SegmentFlags{
SFlag: true,
},
Label: 10203,
})
if err != nil {
return err
}
seglist, err := ptypes.MarshalAny(&api.TunnelEncapSubTLVSRSegmentList{
Weight: &api.SRWeight{
Flags: 0,
Weight: 12,
},
Segments: []*any.Any{segment},
})
if err != nil {
return err
}
pref, err := ptypes.MarshalAny(&api.TunnelEncapSubTLVSRPreference{
Flags: 0,
Preference: 11,
})
if err != nil {
return err
}
cpn, err := ptypes.MarshalAny(&api.TunnelEncapSubTLVSRCandidatePathName{
CandidatePathName: "CandidatePathName",
})
if err != nil {
return err
}
pri, err := ptypes.MarshalAny(&api.TunnelEncapSubTLVSRPriority{
Priority: 10,
})
if err != nil {
return err
}
// Tunnel Encapsulation attribute for SR Policy
tun, err := ptypes.MarshalAny(&api.TunnelEncapAttribute{
Tlvs: []*api.TunnelEncapTLV{
{
Type: 15,
Tlvs: []*anypb.Any{bsid, seglist, pref, cpn, pri},
},
},
})
if err != nil {
return err
}
attrs := []*any.Any{origin, nh, rt, tun}
if _, err := client.AddPath(context.TODO(), &api.AddPathRequest{
TableType: api.TableType_GLOBAL,
Path: &api.Path{
Nlri: nlrisr,
Pattrs: attrs,
Family: &api.Family{Afi: api.Family_AFI_IP, Safi: api.Family_SAFI_SR_POLICY},
Best: true,
SourceAsn: 65000,
},
}); err != nil {
return fmt.Errorf("failed to run AddPath call with error: %v", err)
}
return nil
}
func main() {
conn, err := grpc.DialContext(context.TODO(), "192.168.20.201:50051", grpc.WithInsecure())
if err != nil {
fmt.Printf("fail to connect to gobgp with error: %+v\n", err)
os.Exit(1)
}
client := api.NewGobgpApiClient(conn)
// Testing connection to gobgp by requesting its global config
if _, err := client.GetBgp(context.TODO(), &api.GetBgpRequest{}); err != nil {
fmt.Printf("fail to get gobgp info with error: %+v\n", err)
os.Exit(1)
}
if err := AddSRPolicy(client); err != nil {
fmt.Printf("fail to add SR policy to gobgp with error: %+v\n", err)
os.Exit(1)
}
}
```
## Result of injecting the SR policy
Once the sr policy is injected, gobgp will advertise it to the peers with SR Policy enabled address family. Below is the output collected from Cisco's XRV9K router with enabled SR policy address family. Please note since the information used such as: bsid, endpoint adress etc is not realistic, the router does not install the sr policy, but still, it correctly displays what was programmed.
```
RP/0/RP0/CPU0:xrv9k-r1#sh bgp ipv4 sr-policy [2][99][10.0.0.15]/96
Sun Nov 29 13:05:05.293 EST
BGP routing table entry for [2][99][10.0.0.15]/96
Versions:
Process bRIB/RIB SendTblVer
Speaker 37 37
Last Modified: Nov 29 13:01:21.251 for 00:03:44
Paths: (1 available, best #1)
Not advertised to any peer
Path #1: Received by speaker 0
Not advertised to any peer
Local, (Received from a RR-client)
192.168.20.1 from 192.168.20.201 (192.168.20.201)
Origin IGP, localpref 100, valid, internal, best, group-best
Received Path ID 0, Local Path ID 1, version 37
Extended community: RT:10.0.0.8:0
Tunnel encap attribute type: 15 (SR policy)
bsid 24321, preference 11, num of segment-lists 1
segment-list 1, weight 12
segments: {10203}
Candidate path is not usable
SR policy state is Down, Allocated bsid none
```
|