]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/lib/bgprib.py
Merge pull request #13506 from anlancs/fix/bfdd-vrf-check
[mirror_frr.git] / tests / topotests / lib / bgprib.py
CommitLineData
8a28936d 1#!/usr/bin/env python
acddc0ed 2# SPDX-License-Identifier: GPL-2.0-or-later
8a28936d 3
d5214400 4# Copyright 2018, LabN Consulting, L.L.C.
d5214400 5
787e7624 6#
8a28936d 7# want_rd_routes = [
b4bfe0aa
LB
8# {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1', 'bp': True},
9# {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1', 'bp': False},
787e7624 10#
8a28936d
PZ
11# {'rd':'10:3', 'p':'5.1.0.0/24', 'n':'3.3.3.3'},
12# ]
787e7624 13#
8a28936d
PZ
14# ribRequireVpnRoutes('r2','Customer routes',want_rd_routes)
15#
16# want_unicast_routes = [
17# {'p':'5.1.0.0/24', 'n':'1.1.1.1'},
18# ]
19#
20# ribRequireUnicastRoutes('r1','ipv4','r1-cust1','Customer routes in vrf',want_unicast_routes)
21# ribRequireUnicastRoutes('r1','ipv4','','Customer routes in default',want_unicast_routes)
22#
23
c8e5983d 24from lib.lutil import luCommand, luResult, LUtil
8a28936d 25import json
587e28a4 26import re
8a28936d 27
fea00bad 28
8a28936d 29# gpz: get rib in json form and compare against desired routes
044e2a31 30class BgpRib:
b4bfe0aa 31 def log(self, str):
701a0192 32 LUtil.log("BgpRib: " + str)
b4bfe0aa 33
787e7624 34 def routes_include_wanted(self, pfxtbl, want, debug):
35 # helper function to RequireVpnRoutes
e7294b32 36 for pfx in pfxtbl.keys():
787e7624 37 if debug:
b4bfe0aa 38 self.log("trying pfx %s" % pfx)
2bb8b49c 39 if pfx != want["p"]:
787e7624 40 if debug:
b4bfe0aa 41 self.log("want pfx=" + want["p"] + ", not " + pfx)
787e7624 42 continue
43 if debug:
b4bfe0aa 44 self.log("have pfx=%s" % pfx)
787e7624 45 for r in pfxtbl[pfx]:
b4bfe0aa 46 bp = r.get("bestpath", False)
787e7624 47 if debug:
b4bfe0aa 48 self.log("trying route %s bp=%s" % (r, bp))
787e7624 49 nexthops = r["nexthops"]
50 for nh in nexthops:
51 if debug:
b4bfe0aa 52 self.log("trying nh %s" % nh["ip"])
787e7624 53 if nh["ip"] == want["n"]:
54 if debug:
b4bfe0aa
LB
55 self.log("found %s" % want["n"])
56 if bp == want.get("bp", bp):
57 return 1
58 elif debug:
59 self.log("bestpath mismatch %s != %s" % (bp, want["bp"]))
787e7624 60 else:
61 if debug:
b4bfe0aa 62 self.log("want nh=" + want["n"] + ", not " + nh["ip"])
787e7624 63 if debug:
b4bfe0aa 64 self.log("missing route: pfx=" + want["p"] + ", nh=" + want["n"])
787e7624 65 return 0
8a28936d 66
2bb8b49c 67 def RequireVpnRoutes(self, target, title, wantroutes, debug=0):
787e7624 68 import json
69
ffd3f544 70 logstr = "RequireVpnRoutes " + str(wantroutes)
2bb8b49c
DS
71 # non json form for humans
72 luCommand(
73 target,
74 'vtysh -c "show bgp ipv4 vpn"',
75 ".",
76 "None",
77 "Get VPN RIB (non-json)",
78 )
79 ret = luCommand(
80 target,
81 'vtysh -c "show bgp ipv4 vpn json"',
82 ".*",
83 "None",
84 "Get VPN RIB (json)",
85 )
86 if re.search(r"^\s*$", ret):
87 # degenerate case: empty json means no routes
88 if len(wantroutes) > 0:
89 luResult(target, False, title, logstr)
90 return
90bdefa0 91 luResult(target, True, title, logstr)
2bb8b49c
DS
92 rib = json.loads(ret)
93 rds = rib["routes"]["routeDistinguishers"]
94 for want in wantroutes:
95 found = 0
96 if debug:
97 self.log("want rd %s" % want["rd"])
98 for rd in rds.keys():
99 if rd != want["rd"]:
100 continue
101 if debug:
102 self.log("found rd %s" % rd)
103 table = rds[rd]
104 if self.routes_include_wanted(table, want, debug):
105 found = 1
106 break
107 if not found:
108 luResult(target, False, title, logstr)
109 return
110 luResult(target, True, title, logstr)
8a28936d 111
2bb8b49c 112 def RequireUnicastRoutes(self, target, afi, vrf, title, wantroutes, debug=0):
f89211f7 113 logstr = "RequireUnicastRoutes %s" % str(wantroutes)
787e7624 114 vrfstr = ""
115 if vrf != "":
116 vrfstr = "vrf %s" % (vrf)
8a28936d 117
787e7624 118 if (afi != "ipv4") and (afi != "ipv6"):
b4bfe0aa 119 self.log("ERROR invalid afi")
8a28936d 120
2bb8b49c
DS
121 cmdstr = "show bgp %s %s unicast" % (vrfstr, afi)
122 # non json form for humans
123 cmd = 'vtysh -c "%s"' % cmdstr
124 luCommand(target, cmd, ".", "None", "Get %s %s RIB (non-json)" % (vrfstr, afi))
125 cmd = 'vtysh -c "%s json"' % cmdstr
126 ret = luCommand(
127 target, cmd, ".*", "None", "Get %s %s RIB (json)" % (vrfstr, afi)
128 )
129 if re.search(r"^\s*$", ret):
130 # degenerate case: empty json means no routes
131 if len(wantroutes) > 0:
132 luResult(target, False, title, logstr)
587e28a4 133 return
ffd3f544 134 luResult(target, True, title, logstr)
2bb8b49c
DS
135 rib = json.loads(ret)
136 try:
137 table = rib["routes"]
138 # KeyError: 'routes' probably means missing/bad VRF
139 except KeyError as err:
140 if vrf != "":
141 errstr = "-script ERROR: check if wrong vrf (%s)" % (vrf)
142 else:
143 errstr = "-script ERROR: check if vrf missing"
144 luResult(target, False, title + errstr, logstr)
145 return
146 # if debug:
147 # self.log("table=%s" % table)
148 for want in wantroutes:
149 if debug:
150 self.log("want=%s" % want)
151 if not self.routes_include_wanted(table, want, debug):
152 luResult(target, False, title, logstr)
153 return
154 luResult(target, True, title, logstr)
8a28936d
PZ
155
156
787e7624 157BgpRib = BgpRib()
158
8a28936d 159
2bb8b49c
DS
160def bgpribRequireVpnRoutes(target, title, wantroutes, debug=0):
161 BgpRib.RequireVpnRoutes(target, title, wantroutes, debug)
8a28936d 162
787e7624 163
2bb8b49c
DS
164def bgpribRequireUnicastRoutes(target, afi, vrf, title, wantroutes, debug=0):
165 BgpRib.RequireUnicastRoutes(target, afi, vrf, title, wantroutes, debug)