Skip to content

Commit

Permalink
Operational: Add support for multiple next-hop for routes
Browse files Browse the repository at this point in the history
  • Loading branch information
mattiaswal authored and troglobit committed Jan 8, 2024
1 parent c0e7a6c commit 35d74ce
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 36 deletions.
43 changes: 29 additions & 14 deletions board/netconf/rootfs/libexec/infix/cli-pretty
Original file line number Diff line number Diff line change
Expand Up @@ -60,25 +60,41 @@ class Route:
self.prefix = data.get(f'ietf-{ip}-unicast-routing:destination-prefix', '')
self.protocol = data.get('source-protocol','')[14:]
self.pref = data.get('route-preference','')

interface = get_json_data(None, self.data, 'next-hop', 'outgoing-interface')
address = get_json_data(None, self.data, 'next-hop', f'ietf-{ip}-unicast-routing:next-hop-address')
special = get_json_data(None, self.data, 'next-hop', 'special-next-hop')
if interface:
self.next_hop = interface
elif address:
self.next_hop = address
elif special:
self.next_hop = special
self.next_hop = []
next_hop_list=get_json_data(None, self.data, 'next-hop', 'next-hop-list')
if next_hop_list:
for nh in next_hop_list["next-hop"]:
if(nh.get(f"ietf-{ip}-unicast-routing:address")):
self.next_hop.append(nh[f"ietf-{ip}-unicast-routing:address"])
elif(nh.get("outgoing-interface")):
self.next_hop.append(nh["outgoing-interface"])
else:
self.next_hop.append("unspecified")
else:
self.next_hop = "unspecified"

interface = get_json_data(None, self.data, 'next-hop', 'outgoing-interface')
address = get_json_data(None, self.data, 'next-hop', f'ietf-{ip}-unicast-routing:next-hop-address')
special = get_json_data(None, self.data, 'next-hop', 'special-next-hop')
nh = ""
if interface:
self.nh = interface
elif address:
self.nh = address
elif special:
self.nh = special
else:
self.nh = "unspecified"

self.next_hop.append(nh)
def print(self):
row = f"{self.prefix:<{PadRoute.prefix}}"
row += f"{self.next_hop:<{PadRoute.next_hop}}"
row += f"{self.next_hop[0]:<{PadRoute.next_hop}}"
row += f"{self.pref:>{PadRoute.pref}} "
row += f"{self.protocol:<{PadRoute.protocol}}"
print(row)
for nh in self.next_hop[1:]:
row = f"{'':<{PadRoute.prefix}}"
row += f"{nh:<{PadRoute.next_hop}}"
print(row)

class Software:
"""Software bundle class """
Expand Down Expand Up @@ -384,7 +400,6 @@ def ietf_routing(json, ip="ipv4"):
continue;
routes = get_json_data(None, rib, "routes", "route")


if routes:
for r in routes:
route = Route(r, ip)
Expand Down
36 changes: 23 additions & 13 deletions board/netconf/rootfs/libexec/infix/yanger
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def get_routes(routes, proto, data):
host_prefix_length="128"
for d in data:
new = {}
next_hop = {}

if(d['dst'] == "default"):
d['dst'] = default
if(d['dst'].find('/') == -1):
Expand All @@ -141,18 +141,28 @@ def get_routes(routes, proto, data):
else:
new['route-preference'] = 0

if d['type'] == "blackhole":
next_hop['special-next-hop'] = "blackhole"
if d['type'] == "unreachable":
next_hop['special-next-hop'] = "unreachable"

if d['type'] == "unicast":
if(d.get("gateway")):
next_hop[f'ietf-{proto}-unicast-routing:next-hop-address'] = d['gateway']
elif(d.get("dev")):
next_hop['outgoing-interface'] = d['dev']

new['next-hop'] = next_hop
if d.get('nexthops'):
next_hops = []
for n in d.get('nexthops'):
next_hop = {}
if(n.get("dev")):
next_hop['outgoing-interface'] = n['dev']
if(n.get("gateway")):
next_hop[f'ietf-{proto}-unicast-routing:address'] = n['gateway']
next_hops.append(next_hop)
insert(new,'next-hop','next-hop-list','next-hop',next_hops)
else:
next_hop = {}
if d['type'] == "blackhole":
next_hop['special-next-hop'] = "blackhole"
if d['type'] == "unreachable":
next_hop['special-next-hop'] = "unreachable"
if d['type'] == "unicast":
if(d.get("dev")):
next_hop['outgoing-interface'] = d['dev']
if(d.get("gateway")):
next_hop[f'ietf-{proto}-unicast-routing:next-hop-address'] = d['gateway']
new['next-hop'] = next_hop

out['route'].append(new)
insert(routes, 'routes', out)
Expand Down
3 changes: 0 additions & 3 deletions src/confd/yang/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,6 @@ module infix-routing {
deviation "/ietf-r:routing/ietf-r:ribs/ietf-r:rib/ietf-r:active-route" {
deviate not-supported;
}
deviation "/ietf-r:routing/ietf-r:ribs/ietf-r:rib/ietf-r:routes/ietf-r:route/ietf-r:next-hop/ietf-r:next-hop-options/ietf-r:next-hop-list" {
deviate not-supported;
}

/* OSPF */

Expand Down
23 changes: 17 additions & 6 deletions test/infamy/route.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,29 @@ def _get_routes(target, protocol):
return r.get("routes", {}).get("route",{})
return {}

def _exist_route(target, prefix, nexthop, version,source_protocol):
def _exist_route(target, prefix, nexthop, version, source_protocol):
routes = _get_routes(target, version)
for r in routes:
if r["destination-prefix"] != prefix:
continue
if source_protocol and r.get("source-protocol") != source_protocol:
continue

if not nexthop and not source_protocol: # Only want the route to exist
return True

if source_protocol and r.get("source-protocol") == source_protocol:
return True

nh = r["next-hop"]
if nexthop and nh["next-hop-address"] != nexthop:
continue
return True
next_hop_list = nh.get("next-hop-list")
if nexthop:
if next_hop_list:
for nhl in next_hop_list["next-hop"]:
address = nhl.get("address")
if address == nexthop:
return True
else:
if nh["next-hop-address"] == nexthop:
return True
return False

def ipv4_route_exist(target, prefix, nexthop=None,source_protocol=None):
Expand Down

0 comments on commit 35d74ce

Please sign in to comment.